Im Folgenden werden einige Dutzend Zeilen in eine Variable extrahiert, aber sie werden alle irgendwie in einer einzigen Zeile zusammengefasst. Das heißt, sie verlieren das ursprüngliche Zeilenumbruchzeichen:
ALL_FOUND_LINES=$(find "$TEMP" -type f -name "debug.log*" | xargs -I {} grep -F "STARTING HOST " {})
Gibt es eine Möglichkeit, das Zeilenumbruchzeichen in einer Anweisung wie der obigen beizubehalten?
Antwort1
Wenn Sie dies testen mit
echo $ALL_FOUND_LINES
dann wundert es mich nicht, dass alle Zeilenumbrüche weg sind, da die Shell den Wert in $ALL_FOUND_LINES
Leerzeichen, Tabulatoren und Zeilenumbrüche (standardmäßig) in Wörter aufteilen würde (und dann jedes Wort durch Dateinamengenerierung (Globbing) weiter erweitern würde). Dies geschieht, da die Erweiterung nicht in Anführungszeichen gesetzt ist. Das echo
Dienstprogramm erhält dann eine Liste von Wörtern, die es in einer einzelnen Zeile druckt.
Ein besserer Test wäre
printf '%s\n' "$ALL_FOUND_LINES"
Beachten Sie die Anführungszeichen bei der Variablenerweiterung. Informationen zur Auswahl von printf
over echo
finden Sie unterWarum ist printf besser als echo?.
Ihr Kommando kann verbessert werden in
find "$TEMP" -type f -name 'debug.log*' -exec grep -h -F 'STARTING HOST ' {} +
Anstatt die Dateinamen an weiterzugeben xargs
, lassen wir hier so viele Dateien wie möglich gleichzeitig direkt find
ausführen . Beachten Sie, dass das Entfernen von Ihr Zeilenumbruchproblem nicht löst, da es damit nichts zu tun hatte. Dies würde die Dinge etwas beschleunigen, da weniger Aufrufe von erforderlich sind .grep
debug.log*
xargs
xargs
grep
Siehe auchDie Option -exec von „find“ verstehen.
Wenn Sie mit jeder der gefundenen Zeilen etwas tun müssen, können Sie sie wie folgt durchlaufen:
find "$TEMP" -type f -name 'debug.log*' -exec grep -h -F 'STARTING HOST ' {} + |
while IFS= read -r line; do
# use "$line" here (with quotes)
done
(oder ersetzen Sie die While-Schleife durch einen beliebigen anderen Verarbeitungsschritt, den Sie ausführen müssen.) Es besteht daher nie die Notwendigkeit, alle Daten in einer Variablen als durch eine neue Zeile getrennte Zeichenfolge zu speichern.
Siehe auch„IFS= read -r line“ verstehen
Antwort2
Mann xargs
-L max-lines Use at most max-lines nonblank input lines per command line. Trailing blanks cause an input line to be logically continued on the next input line. Implies -x. -l[max-lines], --max-lines[=max-lines] Synonym for the -L option. Unlike -L, the max-lines argument is optional. If max-lines is not specified, it defaults to one. The -l option is deprecated since the POSIX standard specifies -L instead.