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?
Il est probablement plus facile d'utiliser xargs
. Dans ton cas:
ls -1 | xargs -L1 echo
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/'
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.
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:
for s in `cmd`; do echo $s; done
Si cmd a une grande sortie:
cmd | xargs -L1 echo
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.
Meilleur résultat pour moi:
ls -1 | xargs -L1 -d "\n" CMD
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.