Ü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?

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 && ...

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 '...')

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

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

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.