Angenommen, ich habe eine Ausgabe von einem Befehl (z. B. ls -1
):
a
b
c
d
e
...
Ich möchte echo
nacheinander einen Befehl (sagen wir ) auf jeden anwenden . Z.B
echo a
echo b
echo c
echo d
echo e
...
Was ist der einfachste Weg, dies in Bash zu tun?
ls -1
mag hier ein Beispiel sein, aber es ist wichtig zu bedenken, dass es nicht gut ist, die Ausgabe von zu analysierenls
. Siehe: mywiki.wooledge.org/ParsingLsAntworten:
Es ist wahrscheinlich am einfachsten zu bedienen
xargs
. In deinem Fall:Das
-L
Flag stellt sicher, dass die Eingabe richtig gelesen wird. Aus der Manpage vonxargs
:quelle
ls
automatisch-1
in einem Rohr.ls | xargs -L2 echo
undls -1 | xargs -L2 echo
geben zwei verschiedene Ausgänge. Ersteres ist alles in einer Zeile.xargs
kann nur ausführbare Dateien ausführen, keine Shell-Funktionen oder integrierten Shell-Befehle. Für die erstere ist die beste Lösung wahrscheinlich die mitread
einer Schleife.-L1
ist.Sie können in jeder Zeile eine grundlegende Voranstelloperation verwenden:
Oder Sie können die Ausgabe für komplexere Vorgänge an sed weiterleiten:
quelle
sh: cho: not found a sh: cho: not found
sieht so aus, als würde dase
In-Echo ein sed-Befehl oder so sein.while
Schleife.cmd1 | while read line; do cmd2 $line; done
. Oderwhile read line; do cmd2 $line; done < <(cmd1)
was keine Unterschale erzeugt. Dies ist die vereinfachte Version Ihressed
Befehls:sed 's/.*/echo &/'
"$line"
while-Schleife, um eine Wortteilung zu vermeiden.read -r line
, um einread
Durcheinander mit maskierten Zeichen zu verhindern . Zum Beispielecho '"a \"nested\" quote"' | while read line; do echo "$line"; done
gibt"a "nested" quote"
, was seine Flucht verloren hat. Wenn wir das tunecho '"a \"nested\" quote"' | while read -r line; do echo "$line"; done
, bekommen wir"a \"nested\" quote"
wie erwartet. Siehe wiki.bash-hackers.org/commands/builtin/readSie können eine for-Schleife verwenden :
Beachten Sie, dass die Verwendung von xargs fast immer effizienter ist , wenn der betreffende Befehl mehrere Argumente akzeptiert, da das betreffende Dienstprogramm nur einmal und nicht mehrmals erzeugt werden muss.
quelle
printf '%s\0' * | xargs -0 ...
- Ansonsten ist es ziemlich unsicher mit Dateinamen mit Leerzeichen, Anführungszeichen usw.Sie können sed tatsächlich verwenden, um dies zu tun, vorausgesetzt, es ist GNU sed.
Wie es funktioniert:
quelle
cat /logs/lfa/Modified.trace.log.20150904.pw | sed -r 's/^(.*)(\|006\|00032\|)(.*)$/echo "\1\2\3 - ID `shuf -i 999-14999 -n 1`"/e'
Wenn cmd eine große Ausgabe hat:
quelle
cmd
die Ausgabe Leerzeichen enthält, schlägt das erste fehl.xargs schlägt mit Backslashes, Anführungszeichen fehl. Es muss so etwas sein
xargs -0 Option:
ls -1
Beendet die Elemente mit Zeilenumbrüchen undtr
übersetzt sie in Nullzeichen.Dieser Ansatz ist etwa 50-mal langsamer als das manuelle Iterieren mit
for ...
(siehe Antwort von Michael Aaron Safyan ) (3,55 s gegenüber 0,066 s). Bei anderen Eingabebefehlen wie Suchen, Suchen, Lesen aus einer Datei (tr \\n \\0 <file
) oder ähnlichem müssen Sie jedoch so arbeitenxargs
.quelle
Besseres Ergebnis für mich:
quelle
find . -mindepth 1 -maxdepth 1 -print0 | xargs -0 command
behandelt Fälle, in denen die Ausgabe von nichtls -1
eindeutig ist; Verwenden Sie-printf '%P\0'
eher, als-print0
wenn Sie nicht eine Führung./
auf jedem wollen.Ich mag es, Gawk zu verwenden, um zum Beispiel mehrere Befehle auf einer Liste auszuführen
Das Entkommen der flüchtigen Charaktere kann jedoch etwas haarig werden.
quelle