将IFS设置为拆分换行符时,为什么需要包含退格键?

use*_*931 59 linux bash

我很好奇为什么在设置IFS以分割这样的换行符时需要退格:

IFS=$(echo -en "\n\b")
Run Code Online (Sandbox Code Playgroud)

为什么我不能只使用它(这不起作用)呢?

IFS=$(echo -en "\n")
Run Code Online (Sandbox Code Playgroud)

我正在使用Unix行结尾保存文件的Linux系统上.我已经使用换行符将我的文件转换为十六进制,它肯定只使用"0a"作为换行符.

我已经google了很多,虽然许多页面都记录了换行符后面的换行符,但我找不到解释为什么需要退格键.

-大卫.

spb*_*ick 108

因为正如bash手册所说的关于命令替换:

Bash通过执行命令并用命令的标准输出替换命令替换来执行扩展,删除任何尾随换行符.

所以,通过添加\b你防止删除\n.

更简洁的方法是使用$''引用,如下所示:

IFS=$'\n'
Run Code Online (Sandbox Code Playgroud)

  • 虽然这些应该在某个时候包含在 Posix 中,但目前还没有包含在内,并且在许多地方无法与 /bin/sh 一起使用,因为 /bin/sh 链接到 posix shell,而不是 bash。 (2认同)

小智 47

我记得最简单的方法.在debian wheezy上用bash测试.

IFS="
"
Run Code Online (Sandbox Code Playgroud)

不开玩笑:)

  • 但它不是单行 - 特别是如果您需要恢复旧的 $IFS,如:http://stackoverflow.com/questions/1406966/linux-shell-script-split-string-put-them-in- an-array-then-loop-through-them#comment1250215_1407098 (3认同)

Jim*_*mix 10

由于删除了命令替换中的尾部,因此添加了\b作为换行符后缀的char 。因此, the被用作 的后缀,并且它不再尾随,因此它是从命令替换中返回的。\n\n$(...)\b\n\n

副作用是,它IFS还将包括\bchar 作为分隔符,而不仅仅是\n,这确实是我们唯一的兴趣。

如果您期望\b有一天可能出现在字符串中(为什么不呢?),那么您可以使用:

IFS="$(printf '\nx')" && IFS="${IFS%x}";
Run Code Online (Sandbox Code Playgroud)

returns \n suffixed with x && removes x

现在 IFS 仅包含\nchar。

IFS="$(printf '\nx')" && IFS="${IFS%x}";
echo ${#IFS}; # 1
Run Code Online (Sandbox Code Playgroud)

并且在 , 测试的情况下不会破坏任何内容\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
Run Code Online (Sandbox Code Playgroud)

给出两行(由于 1 \n):

Entry: Foo.
Entry: Bar      Baz Maz Taz.
Run Code Online (Sandbox Code Playgroud)

正如预期的那样。

IFS="$(printf '\nx')" && IFS="${IFS%x}";使用:

IFS="
"
Run Code Online (Sandbox Code Playgroud)

给出相同的结果,但是这两行不能缩进,如果您不小心在“和”之间放置了空格或制表符或任何其他白色字符,那么您将不再只有字符\n,还有一些“奖励” 。除非您在编辑器中使用“显示所有字符”选项,否则很难发现此错误。


Old*_*Pro 9

这是一个黑客,因为使用echo和命令替换.

prompt> x=$(echo -en "\n")
prompt> echo ${#x}
0
prompt> x=$(echo -en "\n\b")
prompt> echo ${#x}
2
Run Code Online (Sandbox Code Playgroud)

所述$()条带后新行和\b防止\n从被,同时非常不可能出现在任何文本尾随换行符.IFS=$'\n'是设置IFS在换行符上拆分的更好方法.

  • 这表明 `\n\b` 格式还包括退格作为 `IFS` 分隔符,所以我认为在某些情况下会被破坏。 (2认同)