Bonjour,
je cherche à supprimer des fichiers dans un répertoire, j'arrive à les lister mais pas à les passer dans la moulinette de rm.
c'est un ls avec plusieurs grep, ex :
ls | grep A | grep -v B | grep .C
et après j'arrive pas à supprimer le résultat.
Pareil avec mv, je veux ajouter une extension à une liste de fichier obtenus avec plusieurs grep.
Merci d'avance.
# boucle et commande
Posté par NeoX . Évalué à 1.
un petit script
qui prend le dossier en parametre ($1)
fait le filtrage de la liste
et le rm pour chaque fichier correspondant.
on peut surement faire plus jolie, plus "propre"
mais au moins ca marche et comme il est tard,
je file me coucher.
[^] # Re: boucle et commande
Posté par jeanjan . Évalué à 1.
[^] # Re: boucle et commande
Posté par stombi (site web personnel) . Évalué à 1.
man find
exemple:
find ./Documents/images/ -name "*.jpg" -exec mv {} {}.plop \;
[^] # Re: boucle et commande
Posté par NeoX . Évalué à 1.
et oui c'est pour enlever entre le caractere n°X et le caractere n°Y
# xargs
Posté par andeus . Évalué à 3.
ls | grep A | grep -v B | grep .C | xargs rm --
[^] # Re: xargs
Posté par Laurent Morel . Évalué à 3.
Pour utiliser xargs de manière plus robuste, il faut demander à ls de quoter/échapper les noms avec -Q (sinon xargs peut couper le nom en deux et rechercher deux fichiers distincts) :
ls -Q | grep A | grep -v B | grep .C | xargs rm --
Si on fait un find (cas plus général ?), alors :
find . -name "toto" -print0 | xargs -0 do_something --
La doc de xargs indique bien ce problème potentiel [ avec une typo dans ma version, ils parlent de l'option -O mais c'est bien -0 (zéro) ]
Quand au script avec la boucle 'for' quelques message plus haut, il souffre du même problème et ne fonctionne pas si un nom de fichier contient un espace : le for va faire deux boucles avec les portions de nom...
Ah les joies du shell ! :(
[^] # Re: xargs
Posté par jeanjan . Évalué à 0.
il me manquait le -Q dans ls, car il y a des espaces dans les noms de fichier.
Merci beaucoup à tous.
[^] # find
Posté par Hugues Hiegel (site web personnel) . Évalué à 3.
ls n'est qu'un outil de *formatage* pour l'utilisateur, il ne devrait pas être utilisé pour les traitements par lots.
De plus, ls est sensible à l'environnement utilisateur (LS_OPTIONS, TIME_STYLE, etc..). Il faut donc penser à lui demander d'ignorer tout cela, ce qui devient vite fastidieux.
Ou alors d'utiliser directement l'expansion shell :
for file in * ; do echo $file | ... ; done
ça à l'énorme avantage de conserver les échappements. Par contre ça ne prend pas les fichiers commençant par un ".". Et si on fait :
for file in * .* ; do .... ; done
s'il n'y a pas de fichiers / dossier qui matche .* ou *, on obtient une erreur, ce qui est gênant.
en plus, ni cette solution, ni ton ls ne gère le cas où tu te retrouves avec un répertoire dans la liste. Et rm va pas être content, du coup. :-)
D'où : find est donc la seule vraie bonne solution.
Ensuite, tous tes grep | grep | grep | ... pourraient être regroupés en deux grep "A|B|C" | grep -v "D|E|F"ce qui serait plus propre.
Mais comme dit, "find" permet de regrouper tous les matches en une seule commande.
find -maxdepth 1 -type f ( -name "A" -o -name "B" ) -a ( ! -name "C" -a ! -name "D" ... ) -exec rm '{}' ';'
à adapter selon tes besoins, évidemment.
[^] # Re: find
Posté par jeanjan . Évalué à 1.
Je vais essayer.
Merci
Suivre le flux des commentaires
Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.