改行文字は、引用符の中に表示されても失われたように見えます。
foo=
for i in 1 2 3; do
foo="$foo$(printf '\n')$i"
done
echo "$foo"
123
実際には、\n
最初の要素の前にaを追加したくないので、代わりにaを使用しますが、${foo:+$(printf '\n')}
まず上記のコードが機能しない理由を理解する必要があります。
答え1
コマンド置換は末尾の改行文字を削除するため、空の文字列$(printf '\n')
と同じです。$(printf '\n\n\n\n')
文字列に改行文字を含めるには、一重引用符または二重引用符の間に入れます。
for i in 1 2 3; do
foo="$foo
$i"
done
改行文字を格納するために変数を定義することはあまり醜くないことがわかります。
nl='
'
for i in 1 2 3; do
foo="$foo$nl$i"
done
ksh93、bash、FreeBSD sh、mksh、zshではまだ通常のshではありませんが、バックスラッシュエスケープを許可するドルの単一引用符を使用することもできます。
for i in 1 2 3; do
foo="$foo"$'\n'"$i"
done
答え2
はい、改行が失われました。コマンドの置き換え 食べるそれらを:
シェルは、サブシェル環境(シェル実行環境を参照)でコマンドを実行し、コマンド置換(「$()」またはバックティックを含むコマンドテキスト)をコマンドの標準出力に置き換えてコマンド置換を拡張する必要があります。交換が終了したら、1 つ以上の <newline> 文字シーケンスを削除します。
ループは必要ありませんfor
。
foo=$(printf '%s\n' 1 2 3)