Wie bereits beantwortet, besteht eine portablere Möglichkeit, eine Variable zu verwenden, darin, sie in Anführungszeichen zu setzen:
$ 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$
Es gibt einen Unterschied in der Implementierung in Bash, mit der Zeile:
l="$(printf '%s\t%s\t%s\n' foo bar baz)"; <<<$l sed -n l
Dies ist das Ergebnis der meisten Muscheln:
/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$
Nur Bash teilt die Variable rechts von, <<<
wenn sie nicht in Anführungszeichen steht.
Dies wurde jedoch in Bash-Version 4.4 korrigiert. Dies
bedeutet, dass der Wert von $IFS
das Ergebnis von beeinflusst <<<
.
Mit der Zeile:
l=(1 2 3); IFS=:; sed -n l <<<"${l[*]}"
Alle Shells verwenden das erste Zeichen von IFS, um Werte zu verbinden.
/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$
Mit "${l[@]}"
wird ein Leerzeichen benötigt, um die verschiedenen Argumente zu trennen, aber einige Shells verwenden den Wert von IFS (Ist das richtig?).
/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$
Bei einem Null-IFS sollten die Werte wie bei dieser Zeile verbunden werden:
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$
Aber sowohl lksh als auch mksh tun dies nicht.
Wenn wir zu einer Liste von Argumenten wechseln:
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$
Sowohl yash als auch zsh halten die Argumente nicht getrennt. Ist das ein Fehler?
echo -e 'foo\tbar\tbaz\n...'
,echo $'foo\tbar\tbaz\n...'
, oderprintf 'foo\tbar\tbaz\n...\n'
oder Variationen davon. Sie müssen nicht jeden Tab oder jede neue Zeile einzeln umbrechen.