Parce que, comme vous le dites, l'entrée de file
doit être noms de fichiers . La sortie de ls
, cependant, n’est que du texte. Le fait qu'il s'agisse d'une liste de noms de fichiers ne change pas le fait qu'il s'agit simplement de texte et non de l'emplacement des fichiers sur le disque dur.
Lorsque vous voyez une sortie imprimée à l'écran, vous voyez du texte. Que ce texte soit un poème ou une liste de noms de fichiers ne fait aucune différence pour l'ordinateur. Tout ce qu'il sait, c'est que c'est du texte. C’est pourquoi vous pouvez transmettre la sortie de ls
aux programmes qui prennent du texte en entrée (bien que vous vous ne devriez vraiment pas, vraiment . ):
$ ls / | grep etc
etc
Ainsi, pour utiliser le résultat d'une commande qui répertorie les noms de fichiers sous forme de texte (tel que ls
ou find
) comme entrée pour une commande prenant des noms de fichiers, vous devez utiliser certaines astuces. L'outil typique pour cela est xargs
:
$ ls
file1 file2
$ ls | xargs wc
9 9 38 file1
5 5 20 file2
14 14 58 total
Comme je l’ai déjà dit, vous ne voulez vraiment pas analyser la sortie de ls
. Quelque chose comme find
est préférable (le print0
imprime un -0
au lieu d'un newilne après chaque nom de fichier et le xargs
de xargs
lui permet de gérer cette entrée; c'est un truc pour que vos commandes fonctionnent avec les noms de fichiers contenant des nouvelles lignes):
$ find . -type f -print0 | xargs -0 wc
9 9 38 ./file1
5 5 20 ./file2
14 14 58 total
Qui a aussi sa propre façon de faire cela, sans avoir besoin de xargs
du tout:
$ find . -type f -exec wc {} +
9 9 38 ./file1
5 5 20 ./file2
14 14 58 total
Enfin, vous pouvez également utiliser une boucle de shell. Cependant, notez que dans la plupart des cas, %code% sera beaucoup plus rapide et plus efficace. Par exemple:
$ for file in *; do wc "$file"; done
9 9 38 file1
5 5 20 file2