xargs -I {} で改行を保持する方法

xargs -I {} で改行を保持する方法

次のコードでは数十行が変数に抽出されますが、何らかの理由ですべてが 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"

変数展開の引用符に注意してください。 の選択については、以下を参照してくださいprintfechoなぜ printf は echo よりも優れているのでしょうか?


あなたのコマンドは次のように改善できます

find "$TEMP" -type f -name 'debug.log*' -exec grep -h -F 'STARTING HOST ' {} +

ここでは、ファイル名を に渡す代わりにxargs、一度にできるだけ多くのファイルに対して を直接find実行します。 を削除しても改行の問題は解決されないことに注意してください。 はこの問題とは何の関係もありません。の呼び出しが少なくなるため、処理速度が少し向上します。grepdebug.log*xargsxargsgrep

参照`find` の -exec オプションを理解する

見つかった各行に対して何かを行う必要がある場合は、次のようにループすることができます。

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 ループを、実行する必要がある他の処理ステップに置き換えます)。したがって、すべてのデータを改行で区切られた文字列として変数に格納する必要はありません。

参照「IFS= read -r line」を理解する

答え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.

関連情報