awk中单引号和双引号之间的区别

lea*_*bee 6 bash quotes awk

我有这样的awk声明:

glb_library="my_library"
awk "
        /^Direct Dependers of/ { next }
        /^---/                 { next }
        /^$glb_library:/       { ver=\$0; next }
                               { gsub(/[[:space:]]/, '', \$0); print ver':'\$0 }
      " file
Run Code Online (Sandbox Code Playgroud)

基本上,我已将awk代码括在双引号中,以便glb_library扩展shell变量.我已经确保逃避$角色以防止外壳扩展$0.遵循这里的指导.

awk 给我这个错误:

awk: syntax error at source line 5
 context is
                                   { gsub(/[[:space:]]/, >>>  ' <<<
Run Code Online (Sandbox Code Playgroud)

我想明白:

  • 在内部使用单引号是否合法awk?为什么''不是像空字符串一样""
  • 是否awk区别对待单引号和双引号?

在我用反斜杠转义单引号并用来\"\"表示空字符串而不是代码之后,我的代码工作''.

Ed *_*ton 7

永远不要用双引号括起任何脚本,否则你就是在判断自己是反斜杠的.这是您尝试执行的操作的语法:

glb_library="my_library"
awk -v glb_library="$glb_library" '
        /^Direct Dependers of/ { next }
        /^---/                 { next }
        $0 ~ "^"glb_library":" { ver=$0; next }
                               { gsub(/[[:space:]]/, ""); print ver":"$0 }
      ' file
Run Code Online (Sandbox Code Playgroud)

  • 不,awk中的字符串分隔符是"",而不是"",所以空字符串是"""` (3认同)

cod*_*ter 6

根据 awk 专家的上述评论和一些研究,我发布了这个答案:

  • awk 字符串用双引号括起来,而不是单引号;更准确地说:单引号不是 awk 中的字符串分隔符,与 shell 不同
  • awk 对单引号没有特殊意义,如果在字符串文字中使用,它们需要用双引号括起来
  • 最好在命令行上使用单引号来包装 awk 语句,这与 OP 使用双引号的代码不同(Ed 清楚地指出了这一点)

进一步澄清:

  • "" 是 awk 中的空字符串,而不是 ''
  • 要在 awk 字符串文字中使用单引号,请将它们括在双引号中,如 "Ed's answers are great!"
  • 在 awk 中处理单引号时采用的其他技术是:

    a) 使用一个变量,如 awk -v q="'" '{ print q }' ...

    b) 使用八进制或十六进制表示法,如 awk '{ print "\047"$0"\047" }' ...


相关文档在这里

  • 我没有使用“特殊字符”一词来表示“特殊含义”。只是改写了答案。 (2认同)

mkl*_*nt0 5

一个务实的总结:

  • 正如Ed Morton 的有用回答明智地建议:
    始终使用引号将您的脚本作为一个整体括起来awk '...',这保证了有过什么没有混乱解释了前面,什么awk最终看到的。

  • 定义字符串awk脚本,总是引号("..."

    • "是唯一awk识别的字符串分隔符。
    • "..."字符串是非插值的(您不能嵌入变量引用),但它们确实识别控制字符序列,例如\n\t
  • 单引号 ( ')在脚本中没有语法意义awk,但是,-如果您'...'按照建议将其用于整个脚本-无论如何您都不能在其中使用文字' ,因为shell 的单引号字符串不允许嵌入 '字符。

    • 如果您确实需要在脚本中使用文字单引号 ( ')awk,您有以下三种选择:
      • 传递定义它的变量,并awk根据直接相邻的字符串文字和变量引用使用的字符串连接:
        awk -v q=\' 'BEGIN { print "I" q "m good." }' # -> I'm good
      • 在里面使用转义序列"...";为了获得最大的可移植性和消除歧义,请使用八进制转义序列 ( \047),而不是十六进制转义序列( \x27):
        awk 'BEGIN { print "I\047m good." }' # -> I'm good
      • 使用'\''(sic) 来“转义”嵌入的'字符。(从技术上讲,正在连接3 个不同的单引号shell字符串文字)谢谢,snr
        awk 'BEGIN { print "I'\''m good" }' # -> I'm good