我很好奇为什么在将 IFS 设置为像这样在换行符上拆分时需要退格:
IFS=$(echo -en "\n\b")
为什么我不能只使用它(这不起作用)呢?
IFS=$(echo -en "\n")
我在使用 Unix 行结尾保存文件的 Linux 系统上。我已经将带有换行符的文件转换为十六进制,它肯定只使用“0a”作为换行符。
我用谷歌搜索了很多,虽然很多页面都记录了换行符后跟退格的解决方案,但我发现没有一个可以解释为什么需要退格。
-大卫。
因为正如 bash 手册所说的关于命令替换:
Bash 通过执行命令并将命令替换替换为命令的标准输出来执行扩展,并删除任何尾随的换行符。
因此,通过添加\b
您可以防止删除\n
.
一种更简洁的方法是使用$''
引用,如下所示:
IFS=$'\n'
我只记得最简单的方法。在 debian wheezy 上使用 bash 进行测试。
IFS="
"
不开玩笑:)
由于使用echo
和命令替换,这是一个 hack。
prompt> x=$(echo -en "\n")
prompt> echo ${#x}
0
prompt> x=$(echo -en "\n\b")
prompt> echo ${#x}
2
去除$()
尾随换行符并\b
防止\n
成为尾随换行符,同时极不可能出现在任何文本中。IFS=$'\n'
是将 IFS 设置为在换行符上拆分的更好方法。
由于删除了命令替换中的拖尾,因此添加\b
了作为换行符后缀的字符。所以 the被用作 的后缀,并且 by that不再是尾随,所以它从命令替换中返回。\n
\n
$(...)
\b
\n
\n
副作用是,这IFS
也将包括\b
char 作为分隔符,而不是 just \n
,这确实是我们唯一感兴趣的。
如果您期望\b
有一天可能会出现在字符串中(为什么不呢?),那么您可以使用:
IFS="$(printf '\nx')" && IFS="${IFS%x}";
那returns \n suffixed with x
&&
removes x
现在 IFS 只包含\n
字符。
IFS="$(printf '\nx')" && IFS="${IFS%x}";
echo ${#IFS}; # 1
\b
在, 测试的情况下什么都不会破坏:
#!/bin/sh
sentence=$(printf "Foo\nBar\tBaz Maz\bTaz");
IFS="$(printf '\nx')" && IFS="${IFS%x}";
for entry in $sentence
do
printf "Entry: ${entry}.\n";
done
给出两行(由于一个\n
):
Entry: Foo.
Entry: Bar Baz Maz Taz.
正如预期的那样。
IFS="$(printf '\nx')" && IFS="${IFS%x}";
使用:
IFS="
"
给出相同的结果,但是这两行不能缩进,如果您不小心在“和”之间放置了空格或制表符或任何其他白色字符,您将不再只有\n
字符,还有一些“奖金” . 除非您在编辑器中使用“显示所有字符”选项,否则很难发现此错误。
只需按 enter 而不分配任何内容也可以。虽然,看起来有人犯了错误,难以理解。
IFS=
#This is a line