Nicht ganz das, was gefragt wurde, weil es keine Pipeline in vi verwendet, sondern sed :
vi $( grep -Irl "foo" | sed -n '2 p')
Ein einfaches Beispiel mit grep (Beachten Sie, dass grep nicht mein einziger Anwendungsfall dafür ist):
$ grep -Irl "foo" path/to/directory/help.js path/to/directory/config.js path/to/directory/task.js
Nun möchte ich die config.js
Datei in Vi öffnen . Meine normale Methode wäre:
$ vi path/to/directory/config.js
die ich entweder mit der tab-Vervollständigung von Hand eingeben oder den Dateinamen aus dem grep-Ergebnis hervorheben und kopieren / einfügen habe.
Ich möchte die Datei jedoch nur durch Angabe des zweiten Ergebnisses des grep-Befehls anzeigen lassen. So etwas wie:
$ grep -Irl "foo" | xargs vi 2
Offensichtlich würde xargs nicht so funktionieren, war nur ein Beispiel. Aber ich versuche herauszufinden, ob es eine Möglichkeit gibt, xargs (oder ein anderes Dienstprogramm) zu verwenden, um dies zu erreichen, und ich finde es nicht.
Etwas, was mir ein Teamkollege vorschlug, war zu verwenden head
und tail
zusammen, wie folgt:
$ grep -Irl "foo" | tail -n 1 | xargs vi
würde task.js abrufen und
$ grep -Irl "foo" | head -n 2 | tail -n 1 | xargs vi
würde config.js abrufen. Ich frage mich, ob es eine weniger ausführliche Methode gibt.
Nicht ganz das, was gefragt wurde, weil es keine Pipeline in vi verwendet, sondern sed :
vi $( grep -Irl "foo" | sed -n '2 p')
Wie wäre es mit
vi $( grep -IrL "foo" | awk "NR==3" )
Dies verwendet AWK, um die entsprechende Zeile zu finden. Die Ausgabe wird dann als Befehlszeilenargument für vi verwendet.
Ich bin oldschool, also bevorzuge ich das Äquivalent, aber die Version ist etwas verpönt.
vi ` grep -IrL "foo" | awk "NR==3" `
Ich habe für diesen Zweck eine Wrapper-Funktion geschrieben, die Sie verwenden können, wenn Sie eine Ausgabezeile eines Befehls wiederverwenden möchten.
Zuerst die Funktion für Bash :
catch() { out="$($@)" nl <<< "$out" read -a r -d '\n' <<< "$out" r=("dummy" "$") }
Dann für zsh :
catch () { out="$($@)" nl <<< "$out" r=("${(@f)out}") }
Die Verwendung ist für beide Varianten gleich. Führen Sie zuerst den gewünschten Befehl aus, der mit catch vorangestellt wird, wodurch die Befehlsausgabe mit einer schönen Nummerierung angezeigt wird:
$ catch grep -Irl "foo" 1 path/to/dir/task.js 2 path/to/dir/help.js 3 path/to/dir/config.js $
Jetzt können Sie jede Zeile in einem folgenden Befehl wiederverwenden, indem Sie den Parameter array verwenden $r
, z
$ wc -c $ 14044 path/to/dir/help.js
In zsh kannst du die geschweiften Klammern ( wc -c $r[2]
) weglassen, aber in bash brauchst du sie leider.
Einige Vorbehalte, die mir in den Sinn kommen:
$r
).