xargs
出力をコマンド引数に分割するための最も柔軟なソリューションです。
また、パラメータ化が単純なため、非常に読みやすく、使いやすいです。
フォーマットは xargs -n $NUMLINES mycommand
です .
たとえば、echo
に ファイル内の個々の行 /tmp/tmp.txt
cat /tmp/tmp.txt | xargs -n 1 echo
または diff
へ 上記の名前のファイル内の行としてリストされている一連のファイルの各ペア:
cat /tmp/tmp.txt | xargs -n 2 diff
-n 2
xargs
を指示します 一度にパイプしたものの 2 行を別々の引数として消費して渡す。
xargs
を調整できます キャリッジ リターン/改行以外の区切り記号で分割します。
man xargs
を使用 グーグルで検索して、この汎用性の高いユーティリティのパワーについて調べてください。
これを行う最善の方法は、ファイルをループにリダイレクトすることです:
# Basic idea. Keep reading for improvements.
FILE=test
while read CMD; do
echo "$CMD"
done < "$FILE"
< "$FILE"
によるリダイレクト cat "$FILE" | while ...
よりもいくつかの利点があります . cat の無用な使用を回避し、不要な子プロセスを節約します。また、ループがサブシェルで実行される一般的な落とし穴も回避します。 Bash では、|
のコマンド パイプラインはサブシェルで実行されます。つまり、ループの終了後に変数の割り当てが失われます。 <
によるリダイレクト にはその問題がないので、 $CMD
を使用できます ループの後、またはループ内の他の変数を変更します。また、不要な子プロセスを回避します。
追加できる改善点がいくつかあります:
IFS=
を追加 だからread
各行の先頭と末尾の空白は削除されません。-r
を追加read
まで バックスラッシュがエスケープ シーケンスとして解釈されないようにします。- 小文字の
CMD
とFILE
. Bash の規則では、環境変数と内部シェル変数のみが大文字です。 printf
を使用echo
の代わりに$cmd
の場合はどちらが安全ですか-n
のような文字列です 、これecho
フラグとして解釈されます。
file=test
while IFS= read -r cmd; do
printf '%s\n' "$cmd"
done < "$file"
あなたが持っているのは、テキスト "cat test"
をパイプすることです ループに入ります。
欲しいもの:
cat test | \
while read CMD; do
echo $CMD
done