以下のコードはこれらの状況を最もよく説明しています。最後の行で末尾の改行文字が出力されないのはなぜですか?各行の出力はコメントに表示されます。私はそれを使用していますGNUバッシュ、バージョン4.1.5
echo -n $'a\nb\n' | xxd -p # 610a620a
x=$'a\nb\n' ; echo -n "$x" | xxd -p # 610a620a
echo -ne "a\nb\n" | xxd -p # 610a620a
x="$(echo -ne "a\nb\n")" ; echo -n "$x" | xxd -p # 610a62
答え1
コマンド置換関数$()
(および近くのいとこ逆引用符)は、特に末尾の改行を削除します。これは記録された行動で、この構成を使用するときは常にこれを知っておく必要があります。
テキスト本文内の改行文字は代替演算子として削除されませんが、シェルから単語を区切ると削除される可能性があるため、結果は引用符を使用するかどうかによって異なります。次の2つの使用法の違いに注意してください。
$ echo -n "$(echo -n 'a\nb')"
a
b
$ !! | xxd -p
610a62
$ echo -n $(echo -n 'a\nb')
a b
$ !! | xxd -p
612062
2番目の例では、出力は引用されず、改行文字は単語区切りとして解釈され、出力では空白として表示されます。
答え2
コマンド置換を使用すると、シェルはサブシェルでコマンドを実行し、標準出力を返します。このプロセスでは、コマンドは単純な区切り文字を返し、それに応じて末尾の文字が削除されるため、IFS文字は意味を失います(引用符がない場合)。たとえば、
$ echo "$(echo -e '\n')" | wc
1 0 1
$ echo -e '\n' | wc
2 0 2
より実質的に、pwd
これはディレクトリ名の間に改行文字があっても機能しますが、そうでは$(pwd)
ありません。
一般的な修正方法は、コマンドの最後に何かを追加してから削除することです。