すでに答えられているように、変数を使用するよりポータブルな方法は、それを引用することです:
$ printf '%s\t%s\t%s\n' foo bar baz
foo bar baz
$ l="$(printf '%s\t%s\t%s\n' foo bar baz)"
$ <<<$l sed -n l
foo bar baz$
$ <<<"$l" sed -n l
foo\tbar\tbaz$
bashの実装には、次のような違いがあります。
l="$(printf '%s\t%s\t%s\n' foo bar baz)"; <<<$l sed -n l
これはほとんどのシェルの結果です:
/bin/sh : foo bar baz$
/bin/b43sh : foo bar baz$
/bin/bash : foo bar baz$
/bin/b44sh : foo\tbar\tbaz$
/bin/y2sh : foo\tbar\tbaz$
/bin/ksh : foo\tbar\tbaz$
/bin/ksh93 : foo\tbar\tbaz$
/bin/lksh : foo\tbar\tbaz$
/bin/mksh : foo\tbar\tbaz$
/bin/mksh-static: foo\tbar\tbaz$
/usr/bin/ksh : foo\tbar\tbaz$
/bin/zsh : foo\tbar\tbaz$
/bin/zsh4 : foo\tbar\tbaz$
<<<
引用符で囲まれていない場合、bashのみが右側の変数を分割します。
ただし、bashバージョン4.4では修正されています。
つまり、の値は$IFS
の結果に影響し<<<
ます。
次の行で:
l=(1 2 3); IFS=:; sed -n l <<<"${l[*]}"
すべてのシェルは、IFSの最初の文字を使用して値を結合します。
/bin/y2sh : 1:2:3$
/bin/sh : 1:2:3$
/bin/b43sh : 1:2:3$
/bin/b44sh : 1:2:3$
/bin/bash : 1:2:3$
/bin/ksh : 1:2:3$
/bin/ksh93 : 1:2:3$
/bin/lksh : 1:2:3$
/bin/mksh : 1:2:3$
/bin/zsh : 1:2:3$
/bin/zsh4 : 1:2:3$
では"${l[@]}"
、異なる引数を区切るためにスペースが必要ですが、一部のシェルはIFSからの値を使用することを選択します(それで正しいですか?)。
/bin/y2sh : 1:2:3$
/bin/sh : 1 2 3$
/bin/b43sh : 1 2 3$
/bin/b44sh : 1 2 3$
/bin/bash : 1 2 3$
/bin/ksh : 1 2 3$
/bin/ksh93 : 1 2 3$
/bin/lksh : 1:2:3$
/bin/mksh : 1:2:3$
/bin/zsh : 1:2:3$
/bin/zsh4 : 1:2:3$
IFSがnullの場合、次の行のように、値が結合される必要があります。
a=(1 2 3); IFS=''; sed -n l <<<"${a[*]}"
/bin/y2sh : 123$
/bin/sh : 123$
/bin/b43sh : 123$
/bin/b44sh : 123$
/bin/bash : 123$
/bin/ksh : 123$
/bin/ksh93 : 123$
/bin/lksh : 1 2 3$
/bin/mksh : 1 2 3$
/bin/zsh : 123$
/bin/zsh4 : 123$
しかし、lkshとmkshはどちらも失敗します。
引数のリストに変更した場合:
l=(1 2 3); IFS=''; sed -n l <<<"${l[@]}"
/bin/y2sh : 123$
/bin/sh : 1 2 3$
/bin/b43sh : 1 2 3$
/bin/b44sh : 1 2 3$
/bin/bash : 1 2 3$
/bin/ksh : 1 2 3$
/bin/ksh93 : 1 2 3$
/bin/lksh : 1 2 3$
/bin/mksh : 1 2 3$
/bin/zsh : 123$
/bin/zsh4 : 123$
yashとzshはどちらも引数を分離しておくことができません。それはバグですか?
echo -e 'foo\tbar\tbaz\n...'
、echo $'foo\tbar\tbaz\n...'
またはprintf 'foo\tbar\tbaz\n...\n'
これらのまたはバリエーション。これにより、各タブまたは改行を個別にラップする必要がなくなります。