Bash 似乎将 LF 转换为 LFCR

Bash seems to convert LF into LFCR

似乎 Bash 将 LF 转换为 LFCR。事实上,下面是一个描述这一点的例子:

text=$(echo -e "foo\nbar\ntir")

将 IFS 设置为 LF 行尾时:

IFS=$(echo -e "\n")

字符串 text 中的 \n 未被解释为如下所示:

for w in $text ; do echo ${w}';' ; done

输出:

foo
bar
tir;

这里是字符“;”用作标记显示 $text 仅包含一个元素,因此 \n 未被解释,尽管它被设置为 IFS。

但是现在,在将 IFS 设置为 LFCR 行尾时:

IFS=$(echo -e "\n\r")

前面命令的输出变成:

foo;
bar;
tir;

标记“;”显示 $text 包含三个元素,因此 $text 中的 \n 已被解释为 \n\r (LFCR) 设置为 IFS。

那么,为什么 Bash 似乎将 LF 转换为 LFCR?如果不是,请问背后的解释是什么?

$IFS 实际上被设置为一个空字符串。

$ IFS=$(echo -e "\n")
$ echo "[$IFS]"
[]

$(...) 捕获输出时,它会删除尾随的换行符。您可以使用 $'...'、shell 语法将 $IFS 设置为换行符,该语法解释转义序列同时避免修整问题。

$ IFS=$'\n'
$ echo "[$IFS]"
[
]
$ text=$'foo\nbar\nbaz\n'
$ printf '%s;\n' $text
foo;
bar;
baz;