Übergeben eines Arguments an mehrere Befehle in einer einzigen Zeile

9

Ich möchte in der Lage sein, mehrere Befehle in derselben Datei in einer einzigen Zeile auszuführen. Die Art und Weise, wie ich das derzeit mache, ist:

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

Mein Bauchgefühl sagt mir, dass es eine Möglichkeit geben sollte, das Dateinamenargument nur einmal anzugeben und es gleichzeitig durch xargsoder etwas Ähnliches an beide Befehle weiterzuleiten :

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

Wenn ich das versuche, wird nur der erste Befehl ausgeführt. Wie kann ich erreichen, was ich tun möchte?

Zaid
quelle

Antworten:

12

Hierfür können Sie eine lokale Variable definieren:

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

Sie können auch alle bedingungslos (Ersetzen &&durch ;) oder parallel (Ersetzen &&durch &) ausführen .

Alternativ können Sie auch die Shell-Verlaufserweiterung verwenden, um auf vorherige Argumente zu verweisen:

commandA file && commandB !:1 && ...
maxschlepzig
quelle
Nicht ganz das, was ich mir vorgestellt hatte, aber eine interessante Alternative.
Zaid
Was ist falsch an dieser Antwort?
Chris
Das ist wirklich cool! Gibt es eine Möglichkeit, keine neue Variable zu definieren?
Benutzer
@user, ich habe eine Alternative hinzugefügt.
Maxschlepzig
8

Für Shells wie Bash, Korn und Z, die eine Prozessersetzung aufweisen, können Sie Folgendes tun:

find file | tee >(xargs commandA) >(xargs commandB) >(xargs perl -ne '...')
Bis auf weiteres angehalten.
quelle
2

Sie können xargs verwenden, um eine Befehlszeile zu erstellen, z.

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

Leiten Sie das Obige einfach in Bash, um es auszuführen:

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

Erweitern des Beispiels auf alle * .c-Dateien im aktuellen Verzeichnis (Ausblenden des ls hier, um eine Ersetzung des Shell-Alias ​​zu verhindern):

\ls -1 *.c | xargs -i -- echo ls -l {}\; wc -l {} | bash
frielp
quelle
Verwendet dies, um eine Liste aller Dateien in Verzeichnissen zu erhalten, deren Name wie "Aufzählungen" lautet: find . -name "*enums*" | xargs -i echo -e echo {}\; ls -lh {}\; echo -e '\n\n' | bash
Matt Lachman
1

Ich würde selbst nicht dafür stimmen. Es ist albern und gefährlich, aber nur um die Möglichkeiten aufzulisten, gibt es:

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

frabjous
quelle