【问题标题】:How to escape backslash and double quotes with awk如何使用 awk 转义反斜杠和双引号
【发布时间】:2016-08-24 09:15:43
【问题描述】:

我有一些 awk 可以重新排列一行。我想转义其中一个变量(例如 $_),这样"\ 用反斜杠转义。

例子:

echo "Ehm, \"hi\", he \\ said" | awk '{$1="" ; print "\"" $_ "\"" }'
" "hi", he \ said"

(不要更改回显,通常我从包含Ehm, "hi", he \ said 的文件中读取)。

我想拥有

" \"hi\", he \\ said" 

相反。我怎样才能做到这一点? awk中有没有可以做到这一点的函数?

【问题讨论】:

  • 在 awk 程序的上下文中,$_ 是什么?
  • @Tom 这意味着,剩下的行
  • 正如this question 的回答中提到的,看起来$_ 最终可以工作,因为_ 的计算结果为0,所以你最终得到$0。在 awk 脚本中看到 $_ 并不常见。使用$0 表示整行。
  • 我认为你应该解耦$1="" 的部分,因为它会产生噪音。除非它是绝对必要的,否则这个问题会从中受益。另外,从您的更新看来,您只想在字符串中添加 ` to any "` 或 ``,最后不是这样吗?
  • @fedorqui 您的评论没有很好地标记,因为我无法理解您写的内容

标签: bash awk escaping


【解决方案1】:

这就是你要找的吗?

$ cat tst.awk
function foo(str) {
    sub(/^[^[:space:]]+/,"",str)   # remove first field
    gsub(/["\\]/,"\\\\&",str)      # put \ before each \ and "
    return "\"" str "\""           # surround with quotes
}
{ print foo($0) }

测试:

$ echo "Ehm, \"hi\", he \\ said" | awk -f tst.awk
" \"hi\", he \\ said"

$ cat file
Ehm, "hi", he \ said

$ awk -f tst.awk file
" \"hi\", he \\ said"

【讨论】:

    【解决方案2】:

    当您使用 Bash 传递字符串时,您必须考虑 echo 本身使用双引号执行的操作。在这里找到它:

    $ echo "Ehm, \"hi\", he \\ said" | awk '1'
    Ehm, "hi", he \ said
    

    使用单引号解决了部分问题:

    $ echo 'Ehm, \"hi\", he \\ said' | awk '1'
    Ehm, \"hi\", he \\ said
    

    话虽如此,现在是时候在字符串周围添加引号了。为此,我们使用带有三个参数的print --> print "\"", $0, "\""

    要删除第一个字段,我们可以这样做in the correct way

    $ echo 'Ehm, \"hi\", he \\ said' | awk '{sub(/^\S+\s*/, ""); print "\"", $0, "\""}'
    "\"hi\", he \\ said"
    

    如果我们只是空白,看起来我们得到了您想要的输出:

    $ echo 'Ehm, \"hi\", he \\ said' | awk '{$1=""; print "\"", $0, "\""}'
    " \"hi\", he \\ said"
    

    【讨论】:

    • 为什么要使用sprintf然后添加1来打印,而您可以只使用printf(甚至只是print)?
    • echo 只是一个例子,通常Ehm, "hi", he \ said 在 awk 处理的文件中。 awk 目前没有转义原始变量的任何内容
    • @TomFenech 哈!因为我太喜欢改变我失去焦点的字符串:D
    • @PeterSmit 那么您应该编辑您的原始问题以使其更具代表性。
    • 我在问题中专门询问了 awk 中的函数来进行转义,但我会进一步澄清
    【解决方案3】:

    你有理由求助于 awk 吗? Bash 完全能够执行字符串操作:

    #!/bin/bash
    
    read -r ignored line <<<'Ehm, "hi", he \ said'
    line=${line//\\/\\\\}
    line=${line//\"/\\\"}
    echo $line
    

    输出

    \"hi\", he \\ said
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-02-13
      相关资源
      最近更新 更多