xargs
ist die flexibelste Lösung zum Aufteilen der Ausgabe in Befehlsargumente.
Es ist auch aufgrund seiner einfachen Parametrierung sehr gut lesbar und einfach zu bedienen.
Format ist xargs -n $NUMLINES mycommand
.
Zum Beispiel an echo
jede einzelne Zeile in einer Datei /tmp/tmp.txt
Sie würden Folgendes tun:
cat /tmp/tmp.txt | xargs -n 1 echo
Oder zu diff
jedes aufeinanderfolgende Dateipaar, das als Zeilen in einer Datei mit dem obigen Namen aufgeführt ist, würden Sie tun:
cat /tmp/tmp.txt | xargs -n 2 diff
Die -n 2
weist xargs
an um zwei Zeilen von dem, was Sie hineingeleitet haben, gleichzeitig zu konsumieren und als separate Argumente zu übergeben.
Sie können xargs
anpassen Trennzeichen neben Wagenrücklauf/Zeilenumbruch aufzuteilen.
Verwenden Sie man xargs
und google, um mehr über die Leistungsfähigkeit dieses vielseitigen Dienstprogramms zu erfahren.
Der beste Weg, dies zu tun, ist, die Datei in die Schleife umzuleiten:
# Basic idea. Keep reading for improvements.
FILE=test
while read CMD; do
echo "$CMD"
done < "$FILE"
Eine Umleitung mit < "$FILE"
hat einige Vorteile gegenüber cat "$FILE" | while ...
. Es vermeidet eine nutzlose Verwendung von cat und erspart einen unnötigen untergeordneten Prozess. Es vermeidet auch eine häufige Falle, bei der die Schleife in einer Subshell ausgeführt wird. In Bash Befehle in einem |
Die Pipeline wird in Subshells ausgeführt, was bedeutet, dass Variablenzuweisungen nach dem Ende der Schleife verloren gehen. Umleitung mit <
hat dieses Problem nicht, also könnten Sie $CMD
verwenden nach der Schleife oder ändern Sie andere Variablen innerhalb der Schleife. Es vermeidet auch unnötige untergeordnete Prozesse.
Es gibt einige zusätzliche Verbesserungen, die vorgenommen werden könnten:
- Fügen Sie
IFS=
hinzu damitread
wird keine führenden und abschließenden Leerzeichen von jeder Zeile entfernen. - Fügen Sie
-r
hinzu bisread
um zu verhindern, dass Backslashes als Escape-Sequenzen interpretiert werden. - Kleinbuchstaben
CMD
undFILE
. Die Bash-Konvention besagt, dass nur Umgebungs- und interne Shell-Variablen in Großbuchstaben geschrieben werden. - Verwenden Sie
printf
anstelle vonecho
was sicherer ist, wenn$cmd
ist eine Zeichenfolge wie-n
, welcheecho
als Flag interpretieren würde.
file=test
while IFS= read -r cmd; do
printf '%s\n' "$cmd"
done < "$file"
Was Sie haben, ist der Text "cat test"
zu leiten in die Schleife.
Sie wollen nur:
cat test | \
while read CMD; do
echo $CMD
done