[英]double and single quotes in wrapping awk codes
我试图从存储在bash中的变量foo
中的一组字符串中提取一个字符串:
foo="I foobar you"
使用awk
,但我得到了不同的结果,当我裹着awk
用单引号和双引号:
$ echo $foo | awk '{print $2}'
$ foobar
$ echo $foo | awk "{print $2}"
$ I foobar you
谁能告诉我为什么'
和"
导致不同的结果,当包装awk
?
这是因为在使用双引号时,shell会在将其传递给awk之前尝试将其扩展为位置参数或变量。 在您的情况下,它尝试扩展$1
但没有找到任何价值,因此扩展结果为空 ,这就是为什么您在awk中获得默认的print操作来打印整行的原因。
之所以我们单引号awk命令,是因为我们想要一个纯字符串,并且在由$1
作为第一个字段(带有默认空格分隔符)的Awk命令本身进行处理之前,不进行任何方式被外壳修改/篡改。
根据外壳的报价规则:
单引号('')可保护左引号和右引号之间的所有内容。 外壳程序不解释引用的文本,将其逐字传递给命令。
就像在您的代码{print $ 2}中一样,它是作为awk传递给动作的:
$ echo $foo | awk '{print $2}'
$ foobar
双引号(“”)可以保护左引号和右引号之间的大多数内容。 Shell至少对引用的文本执行变量和命令替换。 不同的外壳可能会对双引号文本进行其他类型的处理。 因为双引号中的某些字符是由外壳程序处理的,所以必须在文本内对其进行转义。 值得注意的是字符“ $”,“'',“ \\”和“”,如果要直接将它们传递给程序,则所有这些字符都必须在双引号中加上反斜杠。
因此,您必须转义$以获得第二个col的值,如下所示:
$ echo $foo | awk "{print \\$2}"
$ foobar
否则,awk会按照您的情况执行其默认操作,即打印整行。
对于引用Shell变量的最佳做法,@ Ed Mortan表示完全同意。 虽然双引号是默认的,但是如果不小心…。
$ echo "$foo" with double quotes
$ I foobar you
$ echo '$foo' with single quotes
$ $foo
请记住,引用规则是特定于Shell的。 上面的规则仅适用于POSIX投诉的Bourne样式的shell(例如Bash,GNU Bourne-Again Shell)。 与awk,sed,grep等无关。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.