Passer un argument à plusieurs commandes sur une seule ligne

10

J'aimerais pouvoir exécuter plusieurs commandes sur le même fichier sur une seule ligne. La façon dont je le fais actuellement est la suivante:

commandA file && commandB file && perl -ne '...' file

Mon instinct me dit qu'il devrait y avoir un moyen de fournir l'argument du nom de fichier une seule fois et de le diriger vers les deux commandes simultanément via xargsou quelque chose de similaire:

find file | xargs commandA && xargs commandB && xargs perl -ne '...'

Lorsque j'essaie, seule la première commande s'exécute. Comment puis-je réaliser ce que je veux faire?

Zaid
la source

Réponses:

12

Vous pouvez définir une variable locale pour cela:

f=file; commandA $f && commandB $f && ...

Vous pouvez également exécuter tout sans condition (remplacement &&par ;) ou en parallèle (remplacement &&par &).

Vous pouvez également utiliser l'expansion de l'historique du shell pour référencer les arguments précédents:

commandA file && commandB !:1 && ...
maxschlepzig
la source
Pas tout à fait ce que j'avais en tête, mais c'est une alternative intéressante.
Zaid
Quel est le problème avec cette réponse?
Chris
C'est vraiment cool! Existe-t-il un moyen de ne pas définir une nouvelle variable?
utilisateur
@user, j'ai ajouté une alternative.
maxschlepzig
8

Pour les shells tels que Bash, Korn et Z qui ont une substitution de processus, vous pouvez faire ceci:

find file | tee >(xargs commandA) >(xargs commandB) >(xargs perl -ne '...')
En pause jusqu'à nouvel ordre.
la source
2

Vous pouvez utiliser xargs pour construire une ligne de commande, par exemple:

echo file | xargs -i -- echo ls -l {}\; wc -l {}

Il suffit de diriger ce qui précède dans bash pour l'exécuter:

echo file | xargs -i -- echo ls -l {}\; wc -l {} | bash

Extension de l'exemple à tous les fichiers * .c du répertoire courant (échappement du ls ici pour éviter toute substitution d'alias shell):

\ls -1 *.c | xargs -i -- echo ls -l {}\; wc -l {} | bash
frielp
la source
Utilisé pour obtenir une liste de tous les fichiers contenus dans des répertoires dont le nom est comme "enums": find . -name "*enums*" | xargs -i echo -e echo {}\; ls -lh {}\; echo -e '\n\n' | bash
Matt Lachman
1

Je ne voterais pas pour ça moi-même. C'est idiot et dangereux, mais juste dans l'intérêt de lister les façons de faire, il y a:

for cmd in "commandA" "commandB" "perl -ne '...'" ; do eval $cmd file ; done

frabjous
la source