繁体   English   中英

包装awk代码时使用双引号和单引号

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM