web-dev-qa-db-fra.com

Comment appliquer une commande shell à chaque ligne d'une sortie de commande?

Supposons que j'ai une sortie d'une commande (telle que ls -1):

a
b
c
d
e
...

Je veux appliquer une commande (disons echo) à chacun, à son tour. Par exemple.

echo a
echo b
echo c
echo d
echo e
...

Quelle est la façon la plus simple de faire cela à bash?

147
Alex Budovski

Il est probablement plus facile d'utiliser xargs. Dans ton cas:

ls -1 | xargs -L1 echo
173
Michael Mrozek

Vous pouvez utiliser une opération de préparation de base sur chaque ligne:

ls -1 | while read line ; do echo $line ; done

Ou vous pouvez diriger la sortie vers sed pour des opérations plus complexes:

ls -1 | sed 's/^\(.*\)$/echo \1/'
124
Trey Hunner

Vous pouvez utiliser un pour la boucle :

 pour le fichier en *; faire
 echo "$ file" 
 fait 

Notez que si la commande en question accepte plusieurs arguments, l'utilisation de xargs est presque toujours plus efficace car elle n'a à générer que l'utilitaire en question une fois au lieu de plusieurs fois.

8

Vous avez en fait peut utiliser sed pour le faire, à condition que ce soit GNU sed.

... | sed 's/match/command \0/e'

Comment ça marche:

  1. Correspondance de remplacement avec correspondance de commande
  2. Sur substitution commande exécuter
  3. Remplace la ligne substituée par la sortie de la commande.
7
Łukasz Daniluk
for s in `cmd`; do echo $s; done

Si cmd a une grande sortie:

cmd | xargs -L1 echo
3
Marcelo Cantos

xargs échoue avec des barres obliques inverses, des guillemets. Il doit être quelque chose comme

ls -1 |tr \\n \\0 |xargs -0 -iTHIS echo "THIS is a file."

option xargs -0:

-0, --null
          Input  items are terminated by a null character instead of by whitespace, and the quotes and backslash are
          not special (every character is taken literally).  Disables the end of file string, which is treated  like
          any  other argument.  Useful when input items might contain white space, quote marks, or backslashes.  The
          GNU find -print0 option produces input suitable for this mode.

ls -1 termine les éléments avec des caractères de nouvelle ligne, donc tr les traduit en caractères nuls.

Cette approche est environ 50 fois plus lente que l'itération manuelle avec for ... (voir Michael Aaron Safyan s answer) (3.55s contre 0.066s). Mais pour d’autres commandes d’entrée telles que localiser, rechercher, lire à partir d’un fichier (tr \\n \\0 <file) ou similaire, vous devez utiliser xargs comme ceci.

2
Blauhirn

Meilleur résultat pour moi:

ls -1 | xargs -L1 -d "\n" CMD
1
Andrej Pandovich

j'aime utiliser gawk pour exécuter plusieurs commandes sur une liste, par exemple

ls -l | gawk '{system("/path/to/cmd.sh "$1)}'

cependant, la fuite des personnages qui s'échappent peut devenir un peu velue.

0
Chris