$ printf "hi"
hi$ printf "hi\n"
hi
$ printf "hi\\n"
hi
最後の行が印刷されないのはなぜですかhi\n
?
答え1
関係はありませんが、printf
すべてに関連しています。あなたがする主張printf
。
二重引用符で囲まれた文字列では、シェルはに\\
なります\
。したがって、ユーザーが提供する引数はもちろんprintf
実行されます。hi\n
printf
それエスケープシーケンス処理がオンになっています。
二重引用符で囲まれた文字列では、シェルによる\
エスケープは特に␊、、、および文字にのみ影響するように\
制限`
され$
ています"
。あなたはそれがそのまま渡されることがわかります\n
。printf
だからあなたがやっている主張はprintf
実際にhi\n
再び。
フォーマット文字列にエスケープシーケンスを入れるときは注意してくださいprintf
。 一部のみで定義された意味シングル Unix 仕様。たとえば、定義され\n
ていますが、実際には定義されていません。\c
追加読書
答え2
二重引用符の中には、\\n
エスケープされた(引用)バックスラッシュがあり、その後ろがありますn
。これは改行文字を出力しますprintf
。\n
printf
二重引用符は\n
(まだ)文字列です\n
。もう一度文字printf
列を受け取り、\n
改行文字を印刷します。
二重引用符内ではバックスラッシュが特別です。ただ他のバックスラッシュ、改行文字、またはその他の項目が$
前に`
ある場合、または"
。 「Special」は、次の文字の特別な意味を削除することを意味します。バックスラッシュが別の文字の前に来る場合(n
たとえば、バックスラッシュ文字のみ)。
これの説明は次のとおりです。POSIX規格。
フォーマット文字列\n
として印刷するには、またはを使用します。printf
printf '\\n'
printf "\\\\n"
printf '%s' '\n'
通常、printf
書式文字列は一重引用符で囲む必要があり、すべての変数データは書式文字列に挿入する追加の引数として提供する必要があります。
printf 'This is how you write a newline: %s\n' '\n'
答え3
さて、別の視点を追加してみましょう。
これには2つのレベルの解釈があります。 1つはシェルで、もう1つはprintf
受け取った引数のコマンドの解釈(この場合)です。
二重引用符の中シェルはほとんどのバックスラッシュ文字シーケンスを保存し、これは一般的な結果です。
$ printf '%s\n' "\a \b \c \d ... \z \$ \` \\ "
\a \b \c \d ... \z $ ` \
とは別にそのうち$
、、、`
およびは\
シェルのみに該当しますので\
削除してください。
したがって、使用した文字列(およびその他の文字列)をテストすると、次のような結果が得られます。
$ printf '%s\n' "hi\n" "hi\\n" "hi\\\n" "hi\\\\n" "hi\\\\\n"
hi\n
hi\n
hi\\n
hi\\n
hi\\\n
シェルはペアを\\
1つに変換します\
。そして一人で\n
残された\n
。
これで、printf
最初のパラメータと特別な関係があり、明示的にに設定されますthe format
。型パラメータでは、一部の文字は特殊文字です(printfの場合)。例: 次から始まる有効な%
シーケンスそして一部バックスラッシュ文字シーケンス良い:
\\ \a \b \f \n \r \t \v and the special \ddd
したがって、文字列は\n
改行を生成しますが、\\n
改行は生成しません。
$ printf " hi\n hi\\n hi\\\n hi\\\\n"; echo
hi
hi
hi\n hi\n