[ZSH] Commande find avec listing de fichiers (contourné)

Applications, problèmes de configuration réseau
primokorn
Hankyu
Messages : 15
Inscription : lun. 22 août 2016, 14:48

[ZSH] Commande find avec listing de fichiers (contourné)

Message par primokorn »

Bonjour,
J'ai un soucis avec ZSH que je n'ai pas avec BASH.

J'ai 3 images avec extension .webp et un fichier listing.txt qui contient 2 noms de fichiers 1.* et 3.* car je cherche à renommer leur extension de .webp à .webp.nouveau.

Ci-dessous, la situation en exécutant les commandes via BASH.

Code : Tout sélectionner

arnaud@L340:~/Téléchargements/Test$ ls
1.webp  2.webp  3.webp  listing.txt
arnaud@L340:~/Téléchargements/Test$ cat listing.txt 
1.*
3.*
arnaud@L340:~/Téléchargements/Test$ find $(</home/arnaud/Téléchargements/Test/listing.txt) -name "*.webp" -exec sh -c 'mv "$1" "${1%.webp}.webp.nouveau"' _ {} \; 
arnaud@L340:~/Téléchargements/Test$ ls
1.webp.nouveau  2.webp  3.webp.nouveau  listing.txt
arnaud@L340:~/Téléchargements/Test$ 
=> Les 2 fichiers 1.* et 3.* ont bien la nouvelle extension.

Avec ZSH, j'ai 2 messages d'erreur :

Code : Tout sélectionner

╭─ ~/Téléchargements/Test ▓▒░                                                        ░▒▓ ✔  5m 57s  arnaud@L340 
╰─ find $(</home/arnaud/Téléchargements/Test/listing.txt) -name "*.webp" -exec sh -c 'mv "$1" "${1%.webp}.webp.nouveau"' _ {} \; 
find: ‘1.*’: No such file or directory
find: ‘3.*’: No such file or directory
╭─ ~/Téléchargements/Test ▓▒░  
Est-ce que vous voyez pourquoi ça ne passe pas avec ZSH ?
Merci d'avance.
Dernière modification par primokorn le lun. 08 août 2022, 11:25, modifié 4 fois.
Avatar de l’utilisateur
benjarobin
Maître du Kyudo
Messages : 17180
Inscription : sam. 30 mai 2009, 15:48
Localisation : Lyon

Re: [ZSH] Commande find avec listing de fichiers

Message par benjarobin »

Bonjour,
Alors n'étant pas un expert dans le sujet, je ne pourrais pas te répondre en détail.
Mais zsh et bash n'ont pas la même syntaxe, les mêmes règles. Certes c'est assez proche, mais pas similaire.
En bash :

Code : Tout sélectionner

echo $(<./listing.txt)
1.webp 3.webp
En zsh

Code : Tout sélectionner

echo $(<./listing.txt)
1.* 3.*
Sinon tu peux simplifier un peu ce code.
Pour le find tu peux utiliser des ou (les parenthèse autour du ou ne sont pas nécessaire c'est pour l'exemple), et tu devrais utiliser une boucle while :

Code : Tout sélectionner

find \( -name "1*.webp" -o -name "2*.webp" \) | while read f ; do echo mv "$f" "${f/.webp/.webp.nouveau}" ; done
Zsh | KDE | PC fixe : core i7, carte nvidia
Titre d'un sujet : [Thème] Sujet (état) / Règles du forum
primokorn
Hankyu
Messages : 15
Inscription : lun. 22 août 2016, 14:48

Re: [ZSH] Commande find avec listing de fichiers

Message par primokorn »

Bonjour,
Merci pour ta réponse. Bien vu le coup du echo.

Ta commande ne renomme pas les fichiers, si de ton côté ? Ce n'est pas gérable car j'ai un nombre aléatoire de lignes dans mon fichier text et il peut y en avoir quelques dizaines.

EDIT : j’enchaîne plusieurs commandes dans le terminal et tout roule avec ZSH sauf celle-ci donc je vais simplement exécuter un fichier .sh qui est écrit en bash.
Si un connaisseur zsh passe dans le coin, je reste intéressé :)
Avatar de l’utilisateur
benjarobin
Maître du Kyudo
Messages : 17180
Inscription : sam. 30 mai 2009, 15:48
Localisation : Lyon

Re: [ZSH] Commande find avec listing de fichiers

Message par benjarobin »

Ma commande renomme les fichier si tu enlèves le echo... Remplace echo mv par mv . Actuellement elle affiche juste les commandes qui devraient être exécuté
En zsh ceci fonctionne (mais assez moche...) :

Code : Tout sélectionner

cat listing.txt| while read p ; do lf=($(echo $~p)); for f in "$lf[@]" ; do echo mv "$f" "${f%.webp}.webp.nouveau" ; done ; done
Zsh | KDE | PC fixe : core i7, carte nvidia
Titre d'un sujet : [Thème] Sujet (état) / Règles du forum
Avatar de l’utilisateur
papajoke
Elfe
Messages : 769
Inscription : sam. 30 août 2014, 19:54

Re: [ZSH] Commande find avec listing de fichiers

Message par papajoke »

bonjour
primokorn a écrit : dim. 24 juil. 2022, 11:39 EDIT : j’enchaîne plusieurs commandes dans le terminal et tout roule avec ZSH sauf celle-ci donc je vais simplement exécuter un fichier .sh qui est écrit en bash.
vu la longueur de la ligne, je ne vois pas mémoriser/saisir ceci en ligne de commande…
Il ne faut pas se prendre la tête.
Si un fichier ".sh" est un problème, il est toujours simple de taper la commande "bash" depuis zsh - perso je suis avec fish mais je "commute" régulièrement (une fois la semaine?) en bash ou zsh lorsque j'ai une commande (avancée) à entrer.
Arch stable - Kde 5 / zsh - btrfs/mbr - Intel Core i3 - 6Go RAM - GeForce 405 video-nouveau
primokorn
Hankyu
Messages : 15
Inscription : lun. 22 août 2016, 14:48

Re: [ZSH] Commande find avec listing de fichiers

Message par primokorn »

@benjarobin
Oui désolé, j'ai répondu un peu vite pour le coup... Merci pour cette commande qui fonctionne à merveille.

@papajoke
Sur ce cas précis (enchaînement de plusieurs commandes), je passe par un alias.
J'ai quelques scripts quand ça commence à être long.
Avatar de l’utilisateur
benjarobin
Maître du Kyudo
Messages : 17180
Inscription : sam. 30 mai 2009, 15:48
Localisation : Lyon

Re: [ZSH] Commande find avec listing de fichiers (contourné)

Message par benjarobin »

Je pense qu'utiliser un alias est une mauvaise idée. Un script est quand même plus simple et propre. Au pire une fonction, mais un alias pour quelque chose d'aussi complexe...
Zsh | KDE | PC fixe : core i7, carte nvidia
Titre d'un sujet : [Thème] Sujet (état) / Règles du forum
primokorn
Hankyu
Messages : 15
Inscription : lun. 22 août 2016, 14:48

Re: [ZSH] Commande find avec listing de fichiers (contourné)

Message par primokorn »

Je n'ai pas tes connaissances donc je te crois bien volontiers mais j'ai au bas mot entre 80 et 100 commandes pour une trentaine d'alias. (+ une douzaine de fichiers sh)
Les alias ne sont pas tous utilisés en même temps.
C'est sans doute optimisable mais ça dépasse le besoin initial de ce post ;-)
primokorn
Hankyu
Messages : 15
Inscription : lun. 22 août 2016, 14:48

Re: [ZSH] Commande find avec listing de fichiers

Message par primokorn »

Bonjour,
Je reviens vers vous sur cette problématique. La commande ci-dessus ne répond pas aux besoins après des tests réels.

Voici une archive qui contient un vrai cas de test. J'ai un dossier avec le résultat que je souhaite obtenir mais je détaille plus bas mon besoin.

Si je lance la commande ci-dessous dans le dossier Icones_existantes, voilà ce que ça donne :

Code : Tout sélectionner

mv 1.png 1.png.webp.nouveau
mv 3.webp 3.webp.nouveau
Le fichier 1.png doit être renommé 1.png.nouveau.

Le besoin :
- je travaille sur des packs d'icônes pour mobile. J'ai des icônes existantes et via des demandes d'utilisateurs, de nouvelles icônes doivent être intégrées à l'existant. Sauf que certaines nouvelles icônes ont le même nom que des existantes, je cherche donc à les réunir dans un même dossier pour les visualiser et les comparer.
- dossier "Icones_demandees" : ce sont des fichiers d'entrée qui proviennent de nouvelles demandes d'utilisateur et qui ont généralement l'extension PNG (mais ça peut être JPG/JPEG). Lors du déplacement dans le dossier de comparaison "Resultat_souhaite", aucun renommage n'est fait.
- dossier "Icones_existantes" : icônes existantes du pack. Lors du déplacement vers "Resultat_souhaite", l'extension de ces icônes doit être renommée en .existant pour éviter les écrasements de fichiers et pour pouvoir facilement les remettre dans leur dossier d'origine une fois la comparaison faite.
- listing.txt : c'est là que je liste les noms des fichiers à comparer, peu importe leurs extensions

Aujourd'hui, voilà mon enchaînement de commandes qui fonctionnait avec bash :

Code : Tout sélectionner

1. mkdir resultat_souhaite
2. touch resultat_souhaite/listing.txt
3. xsel -b > listing.txt (copie du contenu du presse-papier)
4. cd Icones_existantes
5. find $(<../listing.txt) -name "*.webp" -exec sh -c 'mv "$1" "${1%.webp}.webp.existant"' _ {} \;   <<<<<< renommé les webp en web.existant si le nom colle avec celui du fichier listing.txt
6. find $(<../listing.txt) -name "*.png" -exec sh -c 'mv "$1" "${1%.png}.png.existant"' _ {} \;  <<<<<< idem pour les png (il ne peut y avoir que ces 2 extensions dans le dossier Icones_existantes)
7. mv *.existant ../Resultat_souhaite
8. cd ../Icones_demandees
9. mv $(<../listing.txt) ../Resultat_souhaite
10. rm ../listing.txt
11. cd ../Resultat_souhaite
Note : j'ai adapté mes commandes à ce cas test donc j'espère ne pas avoir fait de boulette :)

Les commandes 5, 6 et 9 sont celles qui me posent problème.
J'espère que mon explication est claire. Elle est un peu longue par contre :D

Un grand merci par avance à ceux qui pourraient se pencher sur mon cas.
Avatar de l’utilisateur
benjarobin
Maître du Kyudo
Messages : 17180
Inscription : sam. 30 mai 2009, 15:48
Localisation : Lyon

Re: [ZSH] Commande find avec listing de fichiers

Message par benjarobin »

Cela me semble horriblement complexe pour quelque chose d'assez simple à faire au final si je comprend bien le besoin. On pourrait remplacer tout ceci par une seule fonction (que tu peux mettre dans ton zshrc)
Cela ne correspond peut être pas à ce que tu veux faire... Mais très sérieusement tu devrait faire un vrai script bash

Code : Tout sélectionner

create_dir_for_compare() {
    local dir1="$1"
    local dir2="$2"
    local dirout="$3"
    shift; shift; shift

    dirout="$(readlink -f "$dirout")"
    mkdir -p "$dirout"

    cd "$dir1"
    find $~@ -name "*.webp" -o -name "*.png" | while read f ; do
        cp "$f" "$dirout/"
    done
    cd - > /dev/null
    cd "$dir2"
    find $~@ -name "*.webp" -o -name "*.png" | while read f ; do
        bf="$(basename "$f")"
        if [ -f "$dirout/$bf" ] ; then
            cp "$f" "$dirout/${bf}.existant"
        else
            cp "$f" "$dirout/"
        fi
    done
    cd - > /dev/null
}
Et tu l’exécute ainsi

Code : Tout sélectionner

create_dir_for_compare Icones_demandees Icones_existantes Resultat_souhaite 1.* 3.*
Zsh | KDE | PC fixe : core i7, carte nvidia
Titre d'un sujet : [Thème] Sujet (état) / Règles du forum
avi3000
Chu Ko Nu
Messages : 404
Inscription : dim. 19 juin 2011, 18:53
Localisation : dans le neuf trois

Re: [ZSH] Commande find avec listing de fichiers

Message par avi3000 »

bonsoir,
en supposant que les dossiers demande et existant soient dans le même répertoire parent:

Code : Tout sélectionner

alias xx='shopt -s nocaseglob; cd demande;mv -nt ../existant *.{jpg,png,jpeg} 2>/dev/null'
il ne restera dans le dossier demande que les fichiers déjà présents dans existant.

Je vous laise lire le manuel bash pour shopt et celui de mv pour mv -nt

:rtfm:
Avatar de l’utilisateur
benjarobin
Maître du Kyudo
Messages : 17180
Inscription : sam. 30 mai 2009, 15:48
Localisation : Lyon

Re: [ZSH] Commande find avec listing de fichiers

Message par benjarobin »

J'avais ceci en tête, sauf que cela ne correspond pas non plus exactement ce qu'il a décrit. Mais oui cela serait plus simple de faire ainsi.
La partie compliquée est la liste de pattern qui vient d'un fichier (ou d'un presse papier), dont on ne sait pas d'où cela vient, est-ce nécessaire, ...
Zsh | KDE | PC fixe : core i7, carte nvidia
Titre d'un sujet : [Thème] Sujet (état) / Règles du forum
primokorn
Hankyu
Messages : 15
Inscription : lun. 22 août 2016, 14:48

Re: [ZSH] Commande find avec listing de fichiers

Message par primokorn »

Ah mais je valide à 100%, il existe quelque chose de plus simple mais on fait avec les moyens du bord :) Surtout que ceci n'est qu'une étape des manipulations que je fais. Ici, on traite le regroupement des icônes pour pouvoir les comparer mais une fois fait, faut les remettre aux bons endroits tout en enlevant le renommage des extensions (mais ça, c'est encore autre chose).
Tant que ça marche et que c'est fiable, ça me va.

Le contenu de listing.txt (obtenu via xsel -b) provient du presse-papier, une copie de cellules Excel d'une VM (et le contenu n'est jamais le même). Aucune saisie n'est faite et il peut y avoir quelques dizaines de cellules/lignes donc difficile de gérer ça à la main dans le terminal.
De plus, j'ai une vingtaine d'applis Android à gérer. Chacune a un nom de dossier différent, c'est pourquoi je passe aujourd'hui par les alias : un par appli.
en supposant que les dossiers demande et existant soient dans le même répertoire parent:
Eh bien non :) Désolé, je ne pensais pas que ça pouvait avoir une importante.
Dans les cas réels, ils ne sont pas du tout au même endroit. Ça reste possible mais ça péterait beaucoup de choses :D

Au passage, j'ai rapidement testé fish hier et c'est bien sympa. Il semble proposer les mêmes possibilités (qui m'intéressent) que zsh donc si vous le connaissez mieux, je suis preneur ici.
Merci encore & bonne journée.
avi3000
Chu Ko Nu
Messages : 404
Inscription : dim. 19 juin 2011, 18:53
Localisation : dans le neuf trois

Re: [ZSH] Commande find avec listing de fichiers

Message par avi3000 »

primokorn a écrit : mar. 02 août 2022, 10:43 en supposant que les dossiers demande et existant soient dans le même répertoire parent:
ce n'est pas une obligation. Ce préalable, conforme à ton code, permettait de simplifier l'exemple.

primokorn a écrit : Aujourd'hui, voilà mon enchaînement de commandes qui fonctionnait avec bash :

Code : Tout sélectionner

1. mkdir resultat_souhaite
2. touch resultat_souhaite/listing.txt
3. xsel -b > listing.txt (copie du contenu du presse-papier)
4. cd Icones_existantes
5. find $(<../listing.txt) -name "*.webp" -exec sh -c 'mv "$1" "${1%.webp}.webp.existant"' _ {} \;   <<<<<< renommé les webp en web.existant si le nom colle avec celui du fichier listing.txt
6. find $(<../listing.txt) -name "*.png" -exec sh -c 'mv "$1" "${1%.png}.png.existant"' _ {} \;  <<<<<< idem pour les png (il ne peut y avoir que ces 2 extensions dans le dossier Icones_existantes)
7. mv *.existant ../Resultat_souhaite
8. cd ../Icones_demandees
9. mv $(<../listing.txt) ../Resultat_souhaite
10. rm ../listing.txt
11. cd ../Resultat_souhaite

après l'exécution de ma première commande,

Code : Tout sélectionner

cd demande
find . -type f|xargs -I {} mv -n {} ../existant/{}.new
te permettras d'avoir dans le dossier existant les 2 versions d'une icône.


Bien que n'ayant pas toutes les infos sur ce que tu veux faire :
  • je ne pense pas que des copier/coller depuis excel soit une bonne solution;
  • un alias par appli ne l'est pas non plus, si le nombre d'appli est conséquent;
  • utiliser le nom de l'appli en argument d'un script ou d'une fonction, me parait plus gérable;
  • le shebang d'un script bash exécutable permet de l'utiliser sous zsh;
  • Se contenter de bash ou sh (KISS), me parait également une meilleure solution. Ce n'est qu'un avis, chacun fait comme il veut.

et pour finir, même si je n'utilise pas zsh :

Code : Tout sélectionner

Run the following command to enable wildcard expansion for zsh.
% set -o GLOB_SUBST
:rtfm:
primokorn
Hankyu
Messages : 15
Inscription : lun. 22 août 2016, 14:48

Re: [ZSH] Commande find avec listing de fichiers

Message par primokorn »

Je suis au boulot, je teste ça jeudi ou vendredi au plus tard.

Pour donner encore plus d'éléments :
Linux me permet de manipuler mes fichiers (icônes en png, jp(e)g, webp et xml) et la VM avec Excel d'intégrer les nouvelles demandes à l'existant (gestion historique, vérification de doublons, détection de caractères spéciaux… la liste est longue). Je pourrais peut-être stocker les valeurs dans un fichier situé dans un dossier partagé avec l'hôte. Je garde l'idée en tête.
J'utilise pas mal de formules et de macros donc je doute que cela puisse être fait sans Excel (à moins d'être un expert en scripts et en bases de données, ce que je ne suis clairement pas), même si j'aimerais bien car une VM Windows, ça rame et ça déconne.

J'ai retenu l'idée de l'argument dans un script général. J'ai trouvé comment saisir un numéro pour sélectionner la variable et dérouler un script par la suite.
Je peux effectivement passer par un script bash exécutable.
Il y a encore du pain sur la planche quoi :)
Avatar de l’utilisateur
papajoke
Elfe
Messages : 769
Inscription : sam. 30 août 2014, 19:54

Re: [ZSH] Commande find avec listing de fichiers

Message par papajoke »

primokorn a écrit : mar. 02 août 2022, 10:43 De plus, j'ai une vingtaine d'applis Android à gérer. Chacune a un nom de dossier différent, c'est pourquoi je passe aujourd'hui par les alias : un par appli.
C'est justement encore une raison pourquoi tu ne devrais pas utiliser tes alias !

Et vouloir écrire une fonction intégrée dans notre shell n'a aucun sens ici ! Le seul intérêt est de vouloir gagner une milliseconde au chargement de cette commande (au détriment d'alourdir notre shell)
primokorn a écrit : mar. 02 août 2022, 10:43 testé fish hier et c'est bien sympa. Il semble proposer les mêmes possibilités (qui m'intéressent) que zsh donc si vous le connaissez mieux, je suis preneur ici.
Tu cherches encore à te faire mal :mrgreen: justement en utilisant des scripts externes (écrits dans n'importe quel langage), tu es beaucoup plus indépendant.
Rappel : le shell (dans ton terminal) n'est qu'une interface utilisateur, nos applications n'ont aucune raison d'êtres dépendance d'une simple interface.
Arch stable - Kde 5 / zsh - btrfs/mbr - Intel Core i3 - 6Go RAM - GeForce 405 video-nouveau
primokorn
Hankyu
Messages : 15
Inscription : lun. 22 août 2016, 14:48

Re: [ZSH] Commande find avec listing de fichiers

Message par primokorn »

Hello,
Alors j'ai beaucoup avancé sur mes macros mais peu sur la partie Linux.

À la suite de nos différents échanges et de mes connaissances en script (j'essaie de vous déranger le moins possible :) ), je vais opter pour des scripts avec un shebang bash et je conserve ZSH comme shell. Fish c'était pour le fun on va dire :humour:

Plutôt que de faire des copier/coller depuis Excel, j'ai des macros qui copie le contenu dans un fichier stocké dans un dossier partagé entre Windows (Invité) et Linux (hôte). Je m'appuie sur son contenu pour mes commandes.
Exemple d'un fichier

J'ai créé un script très simple pour supprimer les fichiers présents dans un dossier mais ça n'a pas fonctionné donc j'ai lancé la commande depuis le shell zsh et idem..
Voilà un résumé du problème :

Code : Tout sélectionner

 ~/Tmp ▓▒░                                                                                ░▒▓ ✔ │ arnaud@L340 
╰─ ls
amazfaces.png   autodoc.png                balance.png                  banking.png
app_tuenti.png  avast_mobile_security.png  banco_procredit_ecuador.png  clipboard_linux_xp.txt
╭─ ~/Tmp ▓▒░                                                                                ░▒▓ ✔ │ arnaud@L340 
╰─ cat clipboard_linux_xp.txt 
amazfaces.png
autodoc.png
avast_mobile_security.png
banking.png
╭─ ~/Tmp ▓▒░                                                                                ░▒▓ ✔ │ arnaud@L340 
╰─ rm $(<clipboard_linux_xp.txt)
rm: cannot remove 'amazfaces.png'$'\r': No such file or directory
rm: cannot remove 'autodoc.png'$'\r': No such file or directory
rm: cannot remove 'avast_mobile_security.png'$'\r': No such file or directory
rm: cannot remove 'banking.png'$'\r': No such file or directory
╭─ ~/Tmp ▓▒░                                                                               ░▒▓ 1 ✘  arnaud@L340 
╰─ 
Visiblement, il y a des caractères spéciaux non visibles à l'oeil nu qui perturbent la sélection.
=> Question : est-ce qu'il est possible de faire une sorte de nettoyage du fichier txt avant la suppression ?

EDIT : c'est lié au style Windows pour les fins de ligne. Réglé via :

Code : Tout sélectionner

tr -d '\r' <clipboard_linux_xp.txt>clipboard_linux_xp_2.txt && mv clipboard_linux_xp_2.txt clipboard_linux_xp.txt 
---

Concernant la "wildcard expansion", est-ce une bonne chose de modifier ce paramètre par défaut ? J'ai retrouvé l'article de linuxhint et j'ai reproduit leur cas de test.
Avec zsh, pour lister les fichiers .log, il suffit de faire

Code : Tout sélectionner

echo $~files
au lieu de

Code : Tout sélectionner

echo $files
primokorn
Hankyu
Messages : 15
Inscription : lun. 22 août 2016, 14:48

Re: [ZSH] Commande find avec listing de fichiers

Message par primokorn »

Dur dur tout ça pour moi mais j'avance.
Dans mon script bash, j'ai ceci :

Code : Tout sélectionner

#!/bin/bash
tr -d '\r' </home/.../dossier_1/clipboard_linux_xp.txt>home/.../dossier_1/clipboard_linux_xp_tmp.txt 
mv /home/.../dossier_1/clipboard_linux_xp_tmp.txt /home/.../dossier_2/clipboard_linux_xp.txt
cd /home/.../dossier_2/
rm -f $(</home/.../dossier_2/clipboard_linux_xp.txt)
Les deux premières c'est pour traiter le format Windows de fin de ligne puis pour envoyer mon fichier txt contenant la liste des fichiers à supprimer au bon endroit.
cd /home... pour aller dans le bon dossier avant suppression.
La dernière supprime les fichiers selon le listing sauf que rien ne se passe ! Si je lance cette dernière ligne manuellement depuis le shell, ça fonctionne. Mystère pour moi... J'ai mis le -f car il me disait rm : missing operand.
Avatar de l’utilisateur
benjarobin
Maître du Kyudo
Messages : 17180
Inscription : sam. 30 mai 2009, 15:48
Localisation : Lyon

Re: [ZSH] Commande find avec listing de fichiers

Message par benjarobin »

Tu peux tout remplacer par ceci :

Code : Tout sélectionner

cat /home/.../dossier_1/clipboard_linux_xp_tmp.txt | dos2unix |  while read f ; do rm "/home/.../dossier_2/$f" ; done
Après si tu utilises des wildcard, cela ne fonctionnera pas
Zsh | KDE | PC fixe : core i7, carte nvidia
Titre d'un sujet : [Thème] Sujet (état) / Règles du forum
primokorn
Hankyu
Messages : 15
Inscription : lun. 22 août 2016, 14:48

Re: [ZSH] Commande find avec listing de fichiers

Message par primokorn »

C'est parfait, merci ! Je continue mes affaires :D
Répondre