shell脚本奇怪,包括sed和backtick

时间:2011-08-01 21:24:36

标签: shell

经过几个小时的剧本战斗后,我将问题缩小到以下几个方面。在命令提示符(bash)上运行它以显示问题:

bash$ echo "\n"
\n
bash$ echo "\n" | sed 's/\\n/---\\&/g'
---\\n
bash$ str=`echo "\n" | sed 's/\\n/---\\&/g'`
bash$ echo $str
\n
bash$ 

我不明白为什么str = ...命令不等同于...中str = output of command。

为什么它不等同于str =“--- \ n”?

我必须在这里遗漏一些基本的东西。

编辑:回应评论:

$ /bin/bash --version
GNU bash, version 4.2.8(1)-release (x86_64-pc-linux-gnu)
Copyright (C) 2011 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>

This is free software; you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

另外,解决方案并不像答案那么简单,只是在反引号中返回管道的第一部分。
注意:

bash$ str=`echo "abc" | sed 's/a/---&/g'`
bash$ echo $str
---abc
bash$

所以不知何故,它是包含\导致问题的字符的组合。我不太清楚这里的行为。

2 个答案:

答案 0 :(得分:2)

其他答案对于某些引用被删除可能是正确的。我最近学到的诀窍是使用$()而不是反叛。

str=$(echo "\n" | sed 's/\\n/---\\&/g')

按预期工作。


更新

以下是它的工作原理。首先考虑这个例子:

$ echo "\\n"
\n
$ echo '\\n'
\\n

在shell中有强弱的引用。弱引用通过“(双引号)表示,强引用通过'(单引号)表示。弱引用不会阻止转义,而强引用会阻止它。而反斜杠具有preserving next character except newline的意思。所以”\ \ n“实际上等于两个字符:\n,因为第一个斜杠被转义。打印出来。强引号,另一方面,不会进行任何转义和'\\ n'变为三个字符。\\n

弱引号的另一个属性是它们阻止强引号生效并使它们按字面解释。

现在,请考虑与您的sed示例相似的示例:

$ echo `echo '\\n'`
\n

那么这里发生了什么?后面的刻度被处理为弱引号,即内部的强引号做任何引用。所以'\\ n'被解释为'\ n',因为\被转义。因此,执行的命令是echo '\n'而不是echo '\\\\n'。这就是你sed发生的事情。

很棒的问题,真让我思考和研究它。

答案 1 :(得分:0)

如果你这样做会有效

str=`echo "\n" | sed 's/\\\\n/---\\\\&/g'`

我的猜测是,在这样的嵌套中丢失了一个引用,但我很想听到更多的背景......