GNU/Linux >> Tutoriels Linux >  >> Linux

Comment passer la sortie de la commande sous forme d'arguments multiples à une autre commande

Pour être complet, je mentionnerai également la substitution de commande et expliquerai pourquoi cela n'est pas recommandé :

cp $(grep -l "pattern" input) directory/

(La syntaxe backtick cp `grep -l "pattern" input` directory/ est à peu près équivalent, mais il est obsolète et peu maniable ; ne l'utilisez pas.)

Cela échouera si la sortie de grep produit un nom de fichier qui contient des espaces blancs ou un métacaractère shell.

Bien sûr, c'est bien de l'utiliser si vous savez exactement quel fichier nomme le grep peut produire, et avoir vérifié qu'aucun d'entre eux n'est problématique. Mais pour un script de production, n'utilisez pas ceci.

Quoi qu'il en soit, pour le scénario de l'OP, où vous devez vous référer à chaque match individuellement et y ajouter une extension, le xargs ou while read les alternatives sont supérieures de toute façon.

Dans le pire des cas (c'est-à-dire des noms de fichiers problématiques ou non spécifiés), passez les correspondances à un sous-shell via xargs :

grep -l "pattern" input |
xargs -r sh -c 'for f; do cp "$f" "$f.bac"; done' _

... où évidemment le script à l'intérieur du for boucle pourrait être arbitrairement complexe.

Dans le cas idéal, la commande que vous souhaitez exécuter est suffisamment simple (ou polyvalente) pour que vous puissiez simplement lui transmettre une liste arbitrairement longue de noms de fichiers. Par exemple, GNU cp a un -t option pour faciliter cette utilisation de xargs (le -t L'option vous permet de placer le répertoire de destination en premier sur la ligne de commande, vous pouvez donc mettre autant de fichiers que vous le souhaitez à la fin de la commande) :

grep -l "pattern" input | xargs cp -t destdir

qui s'étendra dans

cp -t destdir file1 file2 file3 file4 ...

pour autant de correspondances que xargs peut tenir sur la ligne de commande de cp , répété autant de fois qu'il le faut pour passer tous les fichiers à cp . (Malheureusement, cela ne correspond pas au scénario de l'OP ; si vous devez renommer chaque fichier lors de la copie, vous devez transmettre seulement deux arguments par cp invocation :le nom du fichier source et le nom du fichier de destination dans lequel le copier.)

Donc, en d'autres termes, si vous utilisez la syntaxe de substitution de commande et grep produit un vraiment longue liste de correspondances, vous risquez de tomber sur ARG_MAX et les erreurs "Liste d'arguments trop longue" ; mais xargs évitera spécifiquement cela en copiant à la place autant d'arguments qu'il peut passer en toute sécurité à cp à la fois, et exécutant cp plusieurs fois si nécessaire à la place.


Vous pouvez utiliser xargs :

grep 'pattern' input | xargs -I% cp "%" "%.bac"

Vous pouvez utiliser $() pour interpoler la sortie d'une commande. Donc, vous pouvez utiliser kill -9 $(grep -hP '^\d+$' $(ls -lad /dir/*/pid | grep -P '/dir/\d+/pid' | awk '{ print $9 }')) si vous le vouliez.


En plus de la bonne réponse de Chris Jester-Young, je dirais que xargs est également une bonne solution pour ces situations :

grep ... `ls -lad ... | awk '{ print $9 }'` | xargs kill -9

le fera. Tous ensemble :

grep -hP '^\d+$' `ls -lad /dir/*/pid | grep -P '/dir/\d+/pid' | awk '{ print $9 }'` | xargs kill -9

Linux
  1. Comment utiliser la commande Linux grep

  2. Comment affecter la sortie d'une commande Linux à une variable

  3. Comment grep avec la sortie couleur

  4. Comment capturer la sortie d'une commande top dans un fichier sous Linux ?

  5. Sortie de la commande Linux en tant que paramètre d'une autre commande

Comment transmettre un mot de passe à la commande SSH sous Linux

Comment utiliser grep sous Linux

Comment trouver plusieurs chaînes dans des fichiers ? ?

Comment ajouter la sortie à un fichier ?

Comment passer plusieurs arguments à exécuter avec le script .sh

Comment passer la sortie de la commande sous forme de plusieurs arguments à une autre commande