如何使用 \n 作为分隔符将数据附加到变量?

Ern*_*t A 2 shell

新行字符似乎丢失了,即使它们出现在引号中。

foo=
for i in 1 2 3; do
    foo="$foo$(printf '\n')$i"
done

echo "$foo"
123
Run Code Online (Sandbox Code Playgroud)

现在在实践中,我不想\n在第一个元素之前添加 a ,所以我会使用 a${foo:+$(printf '\n')}代替,但首先我必须弄清楚为什么上面的代码不起作用。

Gil*_*il' 7

命令替换删除尾随的换行符,因此$(printf '\n')与 相同$(printf '\n\n\n\n'),即空字符串。

要在字符串中包含换行符,请将其放在单引号或双引号之间。

for i in 1 2 3; do
  foo="$foo
$i"
done
Run Code Online (Sandbox Code Playgroud)

您可能会发现定义一个变量来仅存储换行符并不难看。

nl='
'
for i in 1 2 3; do
  foo="$foo$nl$i"
done
Run Code Online (Sandbox Code Playgroud)

在 ksh93、bash、FreeBSD sh、mksh 和 zsh(但不是普通的 sh)中,您还可以使用单引号,它允许反斜杠转义。

for i in 1 2 3; do
  foo="$foo"$'\n'"$i"
done
Run Code Online (Sandbox Code Playgroud)


cuo*_*glm 6

是的,换行符丢失了,命令替换 吃了它们:

shell 应通过在子 shell 环境中执行命令来扩展命令替换(请参阅 Shell 执行环境)并将命令替换(命令文本加上封闭的“$()”或反引号)替换为命令的标准输出,删除替换末尾的一个或多个 < 换行 > 字符的序列

您不需要for循环,只需:

foo=$(printf '%s\n' 1 2 3)
Run Code Online (Sandbox Code Playgroud)

  • @Wildcard - 它几乎总是派上用场。就像 `cp my_file my_file."$(date)".bak` 如果 `date` 输出中的尾随换行符以 `myfile...bak` 的名称结束,那会非常烦人,你知道吗? (2认同)