Je cherche un aperçu de la façon dont les pipes peuvent être utilisées pour transmettre la sortie standard comme arguments pour d’autres commandes.
Par exemple, considérons ce cas:
ls | grep Hello
La structure de grep suit le modèle: grep SearchTerm PathOfFileToBeSearched
. Dans le cas que j’ai illustré, le mot Hello est pris comme SearchTerm
et le résultat de ls est utilisé comme fichier à rechercher. Mais que faire si je veux le changer? Que faire si je veux que la sortie standard de ls soit le SearchTerm, avec l’argument suivant grep étant PathOfFileToBeSearched
? D’une manière générale, je veux contrôler quel argument le canal remplit avec la sortie standard de la commande précédente. Est-ce possible ou dépend-il de la manière dont le script de la commande (par exemple, grep
) a été écrit?
Je vous remercie beaucoup pour votre aide!
Il existe essentiellement deux options pour cela: la substitution de commandes shell et xargs
. Brian Agnew vient d’écrire sur le premier. xargs
est un utilitaire qui prend son stdin et le transforme en arguments d’une commande à exécuter. Donc tu pourrais courir
ls | xargs -n1 -J % grep -- % PathOfFileToBeSearched
et pour chaque fichier grep -e filename PathOfFileToBeSearched
par ls
, exécutez grep -e filename PathOfFileToBeSearched
pour grep pour le nom de grep -e filename PathOfFileToBeSearched
par ls
dans l’autre fichier que vous spécifiez. Ceci est une invocation inhabituelle de xargs
; En général, il est utilisé pour append un ou plusieurs arguments à la fin d’une commande, alors qu’ici, il doit append exactement un argument à un endroit spécifique. J’ai donc utilisé les arguments -n
et -J
pour arranger cela. L’usage le plus courant serait quelque chose comme
ls | xargs grep -- term
pour rechercher tous les fichiers générés par ls
pour term
. Bien sûr, si vous ne voulez que des fichiers dans le répertoire actuel, vous pouvez le faire plus simplement sans pipeline:
grep -- term *
et de même dans votre arrangement inversé,
for filename in *; do grep -- "$@" PathOfFileToBeSearched done
Il y a un xargs
important avec xargs
: les caractères d’espacement dans les noms de fichiers générés par ls
ne seront pas trop bien traités. Pour ce faire, à condition d’avoir des utilitaires GNU, vous pouvez utiliser find
place.
find . -mindepth 1 -maxdepth 1 -print0 | xargs -0 -n1 -J % grep -- % PathOfFileToBeSearched
utiliser des caractères NUL pour séparer les noms de fichiers au lieu des espaces
grep
lui-même sera construit de telle sorte que si vous n’avez pas spécifié de nom de fichier, il ouvrira stdin (et obtiendra ainsi la sortie de ls
). Il n’y a pas de véritable mécanisme générique ici – simplement une convention.
Si vous souhaitez que le résultat de ls
soit le terme de recherche, vous pouvez le faire via le shell. Utilisez un sous-shell et une substitution pour:
$ grep $(ls) filename.txt
Dans ce scénario, ls
est exécuté dans un sous-shell et sa sortie standard est capturée et insérée dans la ligne de commande en tant qu’argument de grep
. Notez que si la sortie ls
contient des espaces, cela entraînera une confusion pour grep
.