GNU/Linux >> LINUX-Kenntnisse >  >> Linux

So übergeben Sie die Befehlsausgabe als mehrere Argumente an einen anderen Befehl

Der Vollständigkeit halber werde ich auch die Befehlsersetzung erwähnen und erklären, warum dies nicht empfohlen wird:

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

(Die Backtick-Syntax cp `grep -l "pattern" input` directory/ ist ungefähr gleichwertig, aber veraltet und unhandlich; verwenden Sie das nicht.)

Dies schlägt fehl, wenn die Ausgabe von grep erzeugt einen Dateinamen, der Leerzeichen oder ein Shell-Metazeichen enthält.

Natürlich ist es in Ordnung, dies zu verwenden, wenn Sie genau wissen, wie die Datei grep heißt produzieren können, und haben verifiziert, dass keiner von ihnen problematisch ist. Aber für ein Produktionsskript, verwenden Sie dies nicht.

Wie auch immer, für das OP-Szenario, in dem Sie auf jede Übereinstimmung einzeln verweisen und eine Erweiterung hinzufügen müssen, die xargs oder while read Alternativen sind ohnehin überlegen.

Im schlimmsten Fall (d. h. problematische oder nicht spezifizierte Dateinamen) übergeben Sie die Übereinstimmungen über xargs an eine Subshell :

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

... wo offensichtlich das Skript innerhalb des for ist loop beliebig komplex sein kann.

Im Idealfall ist der Befehl, den Sie ausführen möchten, so einfach (oder vielseitig), dass Sie ihm einfach eine beliebig lange Liste von Dateinamen übergeben können. Zum Beispiel GNU cp hat einen -t Option, um diese Verwendung von xargs zu erleichtern (die -t Option erlaubt Ihnen, das Zielverzeichnis an erster Stelle zu setzen auf der Befehlszeile, sodass Sie beliebig viele Dateien an das Ende des Befehls anhängen können):

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

die zu

erweitert wird
cp -t destdir file1 file2 file3 file4 ...

für so viele Übereinstimmungen wie xargs kann auf die Kommandozeile von cp passen , so oft wiederholt, bis alle Dateien an cp übergeben wurden . (Leider entspricht dies nicht dem OP-Szenario; wenn Sie beim Kopieren jede Datei umbenennen müssen, müssen Sie nur zwei Argumente pro cp übergeben Aufruf:der Name der Quelldatei und der Name der Zieldatei, in die kopiert werden soll.)

Mit anderen Worten, wenn Sie die Befehlssubstitutionssyntax und grep verwenden erzeugt ein wirklich lange Liste von Übereinstimmungen, riskieren Sie, auf ARG_MAX zu stoßen und Fehler „Argumentliste zu lang“; aber xargs wird dies speziell vermeiden, indem stattdessen nur so viele Argumente kopiert werden, wie es sicher an cp übergeben werden kann zu einem Zeitpunkt und Ausführen von cp stattdessen mehrmals, falls erforderlich.


Sie können xargs verwenden :

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

Sie können $() verwenden um die Ausgabe eines Befehls zu interpolieren. Sie könnten also kill -9 $(grep -hP '^\d+$' $(ls -lad /dir/*/pid | grep -P '/dir/\d+/pid' | awk '{ print $9 }')) verwenden wenn du wolltest.


Zusätzlich zu Chris Jester-Youngs guter Antwort würde ich sagen, dass xargs ist auch eine gute Lösung für diese Situationen:

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

wird es schaffen. Alle zusammen:

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

Linux
  1. Wie übergebe ich Parameter an einen Alias?

  2. Wie übergibt man die Ausgabe eines Befehls als Argument an einen anderen?

  3. Wie man mit der Farbausgabe umgeht

  4. Wie hängt man die Ausgabe an eine Datei an?

  5. Wie erfasst man die Ausgabe eines Top-Befehls in einer Datei unter Linux?

So speichern Sie die Befehlsausgabe in einer Datei unter Linux

So übergeben Sie das Passwort an den SSH-Befehl in Linux

So verwenden Sie grep unter Linux

Wie finde ich mehrere Zeichenfolgen in Dateien?

Linux-Befehlsausgabe als Parameter eines anderen Befehls

So grep ps-Ausgabe mit Headern