【问题标题】:Why can't I escape quote in gawk?为什么我不能在 gawk 中转义引号?
【发布时间】:2012-02-05 09:47:32
【问题描述】:

我正在尝试执行以下操作,但要么是我太累了,无法思考,要么是因为逃跑而发生了一些奇怪的事情:

scanimage -L | gawk '/N650U/ {print gensub("[\'`]", "", "g", $2)}'
pipe bquote> 

【问题讨论】:

    标签: linux shell gawk


    【解决方案1】:

    这样做的习惯用法是创建一个包含单引号的变量,然后使用它:

    scanimage -L | gawk '/N650U/ {print gensub(q"`", "", "g", $2)}' q="'"
    

    但是,由于您在字符类中使用它,所以这不起作用,因此您需要这样做:

    scanimage -L | gawk '/N650U/ {print gensub("[`'\'']", "", "g", $2)}'
                        <--      1st pair       -->  <--   2nd pair  -->
    

    如果使用bash,另一种选择是使用$'',它确实支持转义单引号

    scanimage -L | gawk $'/N650U/ {print gensub("[`\']", "", "g", $2)}'
    

    你在第二种情况下所做的只是在你的文字单引号之前创建一个单引号对,转义单引号,以便 shell 不会解释它,然后在它之后创建另一个单引号对。

    正则表达式中的单引号示例

    $ echo $'foo`\'' | awk '{gsub(/[o`'\'']/,"#")}1'
    f####
    

    正则表达式外的单引号示例

    $ echo "foo" | awk '{print q$0q}' q="'"
    'foo'
    

    $'' 内包含单引号的示例

    echo $'foo`\'' | awk $'{gsub(/[o`\']/,"#")}1'
    f####
    

    【讨论】:

    • 第一行不起作用,因为你有 q inside 双引号:你想要gensub(q"\", ""...
    • 没有。这样做的习惯用法是改用\047。当您使用变量时,您会强制 awk 使用字符串文字而不是正则表达式文字,从而迫使自己对所有内容进行双重转义(参见手册页或 google)。只需使用foo\047bar 代表foo'bar 即可避免所有的麻烦。请注意,这仅适用于单引号分隔的脚本,如果您的脚本存储在文件中并以 awk -f script 调用,那么您可以只使用文字单引号。
    • @EdMorton 我认为我们不会争论什么是成语,什么不是成语,因为它非常主观。我非常感谢您的评论,但如果我不关心极端便携性,我更喜欢使用 $'' 而不是 \047
    • $'' 除了允许您在脚本中嵌入单引号之外还有什么作用(如果有的话)?在我看来,这似乎不太可能就是它所做的一切,但很高兴能确定。
    【解决方案2】:

    single quotes 中有 no 特殊字符,包括反斜杠 (\)。

    将字符括在单引号 (') 中会保留引号内每个字符的字面值。单引号之间可能不会出现单引号,即使前面有反斜杠。

    您可以将命令更改为:

    $ scanimage -L | awk '/N650U/ {print gensub("['"'"'`]", "", "g", $2)}'
    

    【讨论】:

    • 谢谢你,这正是我正在寻找的。您能否简要解释一下 ` 字符在正则表达式 ['"'"'`] 中的用途
    • @JackalopeZero 在命令中添加额外的空格:'...' "..." '...'。这很简单:将三个字符串连接在一起。
    • 您需要删除空格才能连接。很难阅读。很容易理解。
    【解决方案3】:

    Shell '...' 不支持反斜杠转义。恐怕你必须改用“...”。

    gawk "/N650U/ {print gensub(\"['`]\", \"\", \"g\", \$2)}\"
    

    (注意 shell "..." 确实扩展了 $ 变量,所以你也需要转义它!)

    【讨论】:

    • 更容易逃脱单引号
    • 老实说,在这种令人讨厌的引号字符和反斜杠迷宫中保持清醒的唯一方法是将 gawk 脚本放在自己的文件中。
    【解决方案4】:
    gawk '/N650U/ {print gensub("[\'`]", "", "g", $2)}'
         ^                         ^
         beginning of sq string       end of single quoted string
    

    有点难看,但这有效:

    gawk '/N650U/ {print gensub("['"'"'`]", "", "g", $2)}'
    

    【讨论】:

    • 而不是双引号,只是转义它。丑但不
    • 对,它少了一个字符,但我也认为"['\'']" 使用单引号比"['"'"']" 更容易看到。也许只有我,不知道
    【解决方案5】:

    正确的做法很简单:

    scanimage -L | gawk '/N650U/ {print gensub(/[\047`]/, "", "g", $2)}'
    

    它不会影响将\047 用于单引号,但顺便说一下,考虑到所有其他已发布的解决方案都使用字符串分隔符,请注意在 gsub() 的正则表达式周围使用正则表达式分隔符而不是字符串分隔符第一个论点。这很重要,例如:

    $ printf 'a\\tb\n' | awk '{sub(/\\t/,"X")}1'
    aXb
    $ printf 'a\\tb\n' | awk '{sub("\\t","X")}1'
    a\tb
    $ printf 'a\\tb\n' | awk '{sub("\\\\t","X")}1'
    aXb
    

    在正则表达式上下文中使用字符串分隔符的唯一时间是当您需要将文字与变量连接时,例如:

    awk '{sub("<"var">","")}1'
    

    在手册页中查找字符串和正则表达式分隔符以获取详细信息。

    【讨论】:

      猜你喜欢
      • 2016-10-27
      • 1970-01-01
      • 2017-12-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-07-11
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多