次のコードでは数十行が変数に抽出されますが、何らかの理由ですべてが 1 行にまとめられています。つまり、元の改行文字が失われます。
ALL_FOUND_LINES=$(find "$TEMP" -type f -name "debug.log*" | xargs -I {} grep -F "STARTING HOST " {})
上記のような文で改行文字を保持する方法はありますか?
答え1
これをテストする場合
echo $ALL_FOUND_LINES
すると、シェルは値を$ALL_FOUND_LINES
スペース、タブ、改行 (デフォルト) で単語に分割し (その後、ファイル名生成 (グロブ) によって各単語をさらに展開) するので、改行がすべてなくなるのは驚くことではありません。これは、展開が引用符で囲まれていないために行われます。ユーティリティはecho
次に単語のリストを取得し、それを 1 行に出力します。
より良いテストは
printf '%s\n' "$ALL_FOUND_LINES"
変数展開の引用符に注意してください。 の選択については、以下を参照してくださいprintf
。echo
なぜ printf は echo よりも優れているのでしょうか?。
あなたのコマンドは次のように改善できます
find "$TEMP" -type f -name 'debug.log*' -exec grep -h -F 'STARTING HOST ' {} +
ここでは、ファイル名を に渡す代わりにxargs
、一度にできるだけ多くのファイルに対して を直接find
実行します。 を削除しても改行の問題は解決されないことに注意してください。 はこの問題とは何の関係もありません。の呼び出しが少なくなるため、処理速度が少し向上します。grep
debug.log*
xargs
xargs
grep
見つかった各行に対して何かを行う必要がある場合は、次のようにループすることができます。
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
(または、while ループを、実行する必要がある他の処理ステップに置き換えます)。したがって、すべてのデータを改行で区切られた文字列として変数に格納する必要はありません。
答え2
男の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.