我的命令替换后面的换行符在哪里?


15

以下代码最能说明情况。为什么最后一行不输出尾随换行符char?每行的输出显示在注释中。我正在使用4.1.5版的GNU bash

     echo -n $'a\nb\n'                  | xxd -p  # 610a620a  
           x=$'a\nb\n'   ; echo -n "$x" | xxd -p  # 610a620a
     echo -ne "a\nb\n"                  | xxd -p  # 610a620a
x="$(echo -ne "a\nb\n")" ; echo -n "$x" | xxd -p  # 610a62

4
需要时在罕见情况下的解决方法:tmp=$(somecommand; echo a); tmp=${tmp%a}
吉尔斯(Gills)'


1
@Gilles:上面是您的示例:tmp=$(somecommand; echo a)...这肯定使人们明白了这一点...在我看到示例之前,我的倾向仍然是使用echo -n a...但是,当然!,不需要的-n,因为命令替换将删除推出换行符在任何情况下!...谢谢...
Peter.O 2011年

Answers:


18

命令替换功能$()(及其后缀)专门删除尾随的换行符。这是已记录的行为,使用构造时应始终意识到这一点。

文本主体内的换行符不会由替换运算符删除,但在外壳上进行分词时也可能会删除它们,因此结果取决于您是否使用引号。请注意这两种用法之间的区别:

$ echo -n "$(echo -n 'a\nb')"
a
b

$ !! | xxd -p
610a62

$ echo -n  $(echo -n 'a\nb')
a b

$ !! | xxd -p   
612062

在第二个示例中,输出未加引号,而换行符被解释为单词拆分,使其在输出中显示为空格!


1
谢谢Caleb ..我知道在不加引号的情况下会将单词分隔成单个空格的单词分解功能。这就是为什么我最惊讶地看到我的尾随换行符即使被引用了也消失了...现在,我知道这是因为“正常”行为的命令替换删除一个换行符......哦,这就是生活..并感谢您的链接
Peter.O

6

使用命令替换时,shell在子shell中执行命令,并返回其标准输出。在此过程中,IFS字符失去了重要性(如果未加引号的话),因为该命令返回的是普通的拆分字,因此尾部的字被删除。例如:

$ echo "$(echo -e '\n')" | wc
 1       0       1

$ echo -e '\n' | wc
2       0       2

并且实际上,pwd即使您的目录名之间使用换行符也可以,但$(pwd)不会。

通常的解决方法是在命令末尾添加一些内容,然后将其删除。


1
由于Philomath ...顺便说一下,你第一个例子是语法错误(“WC”不接受一个字符串作为ARG)。对于你的例子是有道理的,第一个可能是echo "$(echo -e '\n')" | wc,它的输出1   0   1,相比2   0   2
Peter.O 2011年

@fred:糟糕,只是一个错字。
Philomath

1
“转换为空格”不是适当的解释,仅涉及一些拆分。特别是,您可以从IFS中删除空间,而这些空间将不充当分隔符。更结束了,你的例子属于一个特例范畴,并没有之间的差异$(pwd)"$(pwd)",看迦勒的答案。
斯特凡希门尼斯

通常的解决办法的建议PS..Your就是我需要什么来清除此一上来..
Peter.O

关于“转换为空格”,请参阅分
Peter.O 2011年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.