IFSを設定するときにechoとprintfの出力が異なるのはなぜですか?

IFSを設定するときにechoとprintfの出力が異なるのはなぜですか?

Ubuntu 20.04でBash 5.0.17を使用しています。

次のコマンドを実行するとき:

IFS=":"; for i in "1:2:3"; do echo $i; done
# output is: 1 2 3

IFS=":"; for i in "1:2:3"; do echo "$i"; done
output is: 1:2:3

IFS=":"; for i in "1:2:3"; do printf "%s\n" $i; done
# output is: 
# 1
# 2
# 3

IFS=":"; for i in "1:2:3"; do printf "%s\n" "$i"; done
# output is: 1:2:3

これは私を混乱させる。

  1. echo各タグを別々の行に印刷するとどうなりますか?
  2. 参照なしでprintf期待どおりに機能するのはなぜですか?$i
  3. 引用時になぜecho失敗するのですか?printf$i

ご協力ありがとうございます

ベストアンサー1

ループはfor i in "1:2:3"; do ...一度だけ実行されます。静的リテラル文字列にはトークン化がなく拡張のみがあり、引用符なしで拡張のみが可能です。他の結果が表示されます。

IFS=:
var="1:2:3"
for i in $var; do...

残りは方法echoprintf動作です。echo引数を空白で連結し、連結文字列と改行文字を印刷します。ただし、printfすべてのパラメータに対応するのに必要な数だけフォーマット文字列を繰り返すので、複数行が発生します。

したがって、最初はecho $i実行 i1:2:3。拡張子は引用符がないため、分割されて3つのパラメータ、、をecho取得します。空白で連結すると、出力に改行文字が加算されます。走るのと同じです。 (それでもシェルコマンドラインで引用されていないスペースの数は重要ではないからです。)1231 2 3echo 1 2 3echo 1 2 "3"

3番目も同様で、printf "%s\n" 1 2 3フォーマット文字列を繰り返し、出力を3行に分割します。このようなジョブは、printf "%s %s\n" 1 2 3繰り返されるたびに2つの引数を使用して1 21行ずつ印刷されます3

おすすめ記事