Hen*_*ley 5 unix shell scripting ksh
有人能解释为什么这两个命令的输出不同吗?
$ echo "NewLine1\nNewLine2\n"
NewLine1
NewLine2
<-- Note 2nd newline here
$ echo "$(echo "NewLine1\nNewLine2\n")"
NewLine1
NewLine2
$ <-- No second newline
Run Code Online (Sandbox Code Playgroud)
有没有什么好办法可以在"$(....)"中将新行保留在输出的末尾?我想过只是添加一个虚拟字母并删除它,但我很想知道为什么这些新线条会消失.
因为这就是 POSIX 指定的内容,并且在 Bourne shell 中一直如此:
2.6.3 命令替换
命令替换允许用命令的输出来替换命令名称本身。当命令包含如下时,将发生命令替换:
$(命令)
或(反引号版本):
`命令`
shell 应通过在子 shell 环境中执行命令(请参阅 Shell 执行环境)并用命令的标准输出替换命令替换(命令文本加上“$()”或反引号)来扩展命令替换,删除替换末尾的一个或多个 <newline> 字符的序列。输出结束前嵌入的<newline>字符不得被删除;但是,它们可能会被视为字段分隔符并在字段拆分期间被消除,具体取决于 IFS 的值和有效的引用。如果输出包含任何空字节,则行为未指定。
保留最终换行符的一种方法是
VAR="$(command; echo x)" # Append x to keep newline(s).
VAR=${VAR%x} # Chop x.
Run Code Online (Sandbox Code Playgroud)
可见:
$ x="$(whoami; echo x)" ; printf '<%s>\n' "$x" "${x%x}"
<user
x>
<user
>
Run Code Online (Sandbox Code Playgroud)
但为什么要删除尾随换行符呢?因为很多时候你都希望如此。我也在 perl 中编程,我无法计算读取一行或变量然后需要截断换行符的次数:
while (defined ($string = <>)) {
chop $string;
frobnitz($string);
}
Run Code Online (Sandbox Code Playgroud)