在AWK中转义反斜杠进行命令替换

6

我将尝试在AWK中转义反斜杠。以下是我的示例:

假设我有一个变量

$echo $a
hi

以下内容有效。
$echo $a | awk '{printf("\\\"%s\"",$1)'}
\"hi"

但是,当我尝试使用命令替换将相同命令的输出保存到变量中时,我会收到以下错误:

$ q=`echo $a | awk '{printf("\\\"%s\"",$1)'}`
awk: {printf("\\"%s\"",$1)}
awk:               ^ backslash not last character on line

我不明白为什么命令替换会导致AWK出现错误。非常感谢您的帮助。


请参考这个问题以清楚了解反引号内反斜杠的行为。 - Dhruv
3个回答

3

试试这个:

q=$(echo $a | awk '{printf("\\\"%s\"",$1)}')

测试:

$ a=hi
$ echo $a
hi
$ q=$(echo $a | awk '{printf("\\\"%s\"",$1)}')
$ echo $q
\"hi"

更新:

它会被更新,只是会变得有点混乱。

q=`echo $a | awk '{printf("\\\\\"%s\"",$1)}'`

测试:

$ b=hello
$ echo $b
hello
$ t=`echo $b | awk '{printf("\\\\\"%s\"",$1)}'`
$ echo $t
\"hello"

Reference


4
根据bash的手册页面:当使用旧式的反引号替换形式时,反斜杠保留其字面含义,除非后面跟着$、`或\。因此,如果你发现两个反斜杠,它们的含义是通常的。否则,它将被按字面意思解释,所以无论是用5个还是6个都可以。前者之所以有效是因为每两个中间有一个被输出,并且最后一个没有特殊含义。而对于后者,因为所有的反斜杠都被解释并输出三个反斜杠,正好符合你的要求。 - Birei
如果有人想知道为什么最终表达式变成q=\"hi"时,引号和反斜杠没有被移除,那是因为这个移除只针对不属于任何类型扩展的部分。请阅读引号移除 - Dhruv

1

不要养成使用反引号、引号和解析 shell 变量到 awk 的坏习惯。正确的做法是:

$ shell_var="hi"

$ awk -v awk_var="$shell_var" -v c='\' 'BEGIN{printf "%s%s\n",c,awk_var}'
\hi

$ res=$(awk -v awk_var="$shell_var" -v c='\' 'BEGIN{printf "%s%s\n",c,awk_var}')

$ echo "$res"
\hi

在这种情况下,正确的方式是 q=\\\"$a\"。不需要使用命令替换,echo,awk或管道。 - Uwe
使用Shell变量和反斜杠来与awk正确交互的方法不是不使用awk吧?我认为不是这样的...请不要字面理解问题,只是一个例子。 - Chris Seymour
抱歉,我错了,这不是原帖作者真正遇到的问题,而是一个简化版本。 - Uwe

1

反引号命令中的引用有些复杂,主要是因为相同的标记用于开始和结束反引号命令。因此,为了嵌套反引号命令,必须使用反斜杠转义内部命令的反引号。此外,反斜杠可以用于引用其他反斜杠和美元符号(后者实际上是多余的)。如果反引号命令包含在双引号中,则反斜杠也可以用于引用双引号。当shell读取反引号命令时,所有这些反斜杠都将被删除。所有其他反斜杠保持不变。

新的$(...)避免了这些麻烦。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接