包装awk代码中的双引号和单引号

时间:2017-12-06 11:36:47

标签: bash awk

我正在尝试从bash中存储在变量中的一组字符串中提取字符串,例如foo

foo="I foobar you"

使用awk,但当我用单引号和双引号包裹awk时,我得到了不同的结果:

$ echo $foo | awk '{print $2}'
$ foobar

$ echo $foo | awk "{print $2}"
$ I foobar you

有人可以告诉我为什么'"在包装awk时会导致不同的结果吗?

2 个答案:

答案 0 :(得分:3)

这是因为当使用双引号时,shell会尝试将其作为位置参数或变量展开,然后再将其传递给awk。在您的情况下,它会尝试展开$1,但没有找到它的值,因此扩展结果为 nothing ,这就是为什么您在awk中打​​印默认打印操作的原因整条线。

我们单独引用awk命令的原因是我们想要一个普通的字符串,并且在由Awk命令本身处理之前,不会被shell修改/篡改,该命令本身将$1理解为第一个字段(带有默认空格分隔符)

答案 1 :(得分:1)

根据shell引用规则:

  • 单引号('')保护开始和结束引号之间的所有内容。 shell不对引用的文本进行解释,将其逐字传递给命令。

    在你的代码{print $ 2}中传递,因为它是作为动作的awk:
    $ echo $foo | awk '{print $2}'
    $ foobar

  • 双引号(“”)保护开头报价和收盘价之间的大部分内容。 shell至少对引用的文本执行变量和命令替换。不同的shell可能会对双引号文本执行其他类型的处理。由于双引号文本中的某些字符由shell处理,因此必须在文本中对其进行转义。值得注意的是字符'$',''','\'和'“',如果要将它们传递给程序,则必须在双引号文本中加上反斜杠。

    所以你必须逃避$以获得第二列的值为:
    $ echo $foo | awk "{print \$2}"
    $ foobar
    否则awk会按照您的情况执行打印整行的默认操作。

  • 完全同意@Ed Mortan关于引用shell变量的最佳实践。虽然双引号是默认的,但如果不小心...... $ echo "$foo" with double quotes
    $ I foobar you

    $ echo ‘$foo’ with single quotes
    $ $foo

  • 请记住,引用规则特定于shell。以上规则仅适用于POSIX-complaint,Bourne风格的shell(如Bash,GNU Bourne-Again Shell)。它与awk,sed,grep等无关......