So behalten Sie Zeilenumbrüche bei xargs -I {} bei

So behalten Sie Zeilenumbrüche bei xargs -I {} bei

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_LINESLeerzeichen, 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 echoDienstprogramm 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 printfover echofinden 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 findausfü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 .grepdebug.log*xargsxargsgrep

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.

verwandte Informationen