439 votes

Faire en sorte que xargs exécute la commande une fois pour chaque ligne d'entrée

Comment puis-je faire en sorte que xargs exécute la commande exactement une fois pour chaque ligne d'entrée donnée ? Le comportement par défaut de xargs est de découper les lignes et d'exécuter la commande une fois, en passant plusieurs lignes à chaque instance.

Desde http://en.wikipedia.org/wiki/Xargs :

find /path -type f -print0 | xargs -0 rm

Dans cet exemple, find alimente l'entrée de xargs avec une longue liste de noms de fichiers. xargs divise ensuite cette liste en sous-listes et appelle rm une fois pour chaque sous-liste. Ceci est plus efficace que cette version fonctionnellement équivalente :

find /path -type f -exec rm '{}' \ ;

Je sais que find a le drapeau "exec". Je ne fais que citer un exemple illustratif tiré d'une autre ressource.

5 votes

Dans l'exemple que vous donnez, find /path -type f -delete serait encore plus efficace :)

0 votes

Essayez de ne pas utiliser xargs...

7 votes

OP, je sais que cette question est très ancienne, mais elle apparaît toujours sur Google et, à mon avis, la réponse acceptée est fausse. Voir ma réponse plus longue ci-dessous.

11voto

Richard Points 39

Une autre alternative...

find /path -type f | while read ln; do echo "processing $ln"; done

9voto

find path -type f | xargs -L1 command 

est tout ce dont vous avez besoin.

4voto

La commande suivante trouvera tous les fichiers (-type f) dans /path et ensuite les copier en utilisant cp dans le dossier en cours. Notez l'utilisation de -I % pour spécifier un caractère de remplacement dans le cp afin que les arguments puissent être placés après le nom du fichier.

find /path -type f -print0 | xargs -0 -I % cp % .

Testé avec xargs (GNU findutils) 4.4.0

2voto

Readonly Points 48598

Vous pouvez limiter le nombre de lignes, ou d'arguments (s'il y a des espaces entre chaque argument) en utilisant les drapeaux --max-lines ou --max-args, respectivement.

  -L max-lines
         Use at most max-lines nonblank input lines per command line.  Trailing blanks cause an input line to be logically continued on the next  input
         line.  Implies -x.

  --max-lines[=max-lines], -l[max-lines]
         Synonym  for  the -L option.  Unlike -L, the max-lines argument is optional.  If max-args is not specified, it defaults to one.  The -l option
         is deprecated since the POSIX standard specifies -L instead.

  --max-args=max-args, -n max-args
         Use at most max-args arguments per command line.  Fewer than max-args arguments will be used if the size (see  the  -s  option)  is  exceeded,
         unless the -x option is given, in which case xargs will exit.

1voto

Mohammad Karmi Points 435

Les réponses de @Draemon semblent être correctes avec "-0" même avec un espace dans le fichier.

J'ai essayé la commande xargs et j'ai découvert que "-0" fonctionne parfaitement avec "-L". Même les espaces sont traités (si l'entrée est à terminaison nulle). voici un exemple :

#touch "file with space"
#touch "file1"
#touch "file2"

Ce qui suit va diviser les nuls et exécuter la commande sur chaque argument de la liste :

 #find . -name 'file*' -print0 | xargs -0 -L1
./file with space
./file1
./file2

donc -L1 exécutera l'argument sur chaque caractère à terminaison nulle s'il est utilisé avec "-0". Pour voir la différence, essayez :

 #find . -name 'file*' -print0 | xargs -0 | xargs -L1
 ./file with space ./file1 ./file2

même cela s'exécutera une fois :

 #find . -name 'file*' -print0  | xargs -0  | xargs -0 -L1
./file with space ./file1 ./file2

La commande ne s'exécutera qu'une seule fois car le "-L" ne se sépare pas sur un octet nul. Vous devez fournir à la fois "-0" et "-L" pour que cela fonctionne.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X