【问题标题】:Escaping sed strings correctly正确转义 sed 字符串
【发布时间】:2011-01-05 17:57:08
【问题描述】:

我有一个正则表达式和替换模式,它们都已在 Notepad++ 中对我的输入数据进行了测试并且可以正常工作。但是,当我将它们放入 sed 表达式时,没有任何匹配项。

这里是 sed 命令:

 # SEARCH = ([a-zA-Z0-9.]+) [0-9] (.*)
 # REPLACE = \2 (\1)

 sed -e 's/\([a-zA-Z0-9.]+\) [0-9] \(.*\)/\2 \(\1\)/g'

这是数据的一个样本:

jdoe 1 Doe, John
jad 1 Doe, Jane
smith 2 Smith, Jon

以及所需的输出:

Doe, John  (jdoe)
Doe, Jane  (jad)
Smith, Jon (smith)

我尝试在 sed 表达式中删除和添加转义符到不同的字符,但要么没有匹配,要么如下:

sed: -e expression #1, char 42: invalid reference \2 on `s' command's RHS

如何正确转义?

【问题讨论】:

    标签: bash sed escaping


    【解决方案1】:

    我通常发现使用 -r 开关更容易,因为这意味着转义类似于大多数其他语言:

    sed -r 's/([a-zA-Z0-9.]+) [0-9] (.*)/\2 (\1)/g' file1.txt
    

    【讨论】:

      【解决方案2】:

      不使用-r开关时,加号需要转义。

      【讨论】:

        【解决方案3】:

        其他人已经说过的一些警告和补充:

        1. -r 选项是一个 GNU 扩展,用于启用扩展的正则表达式。 BSD 派生的 sed 使用 -E 代替。
        2. SedGrep 使用 Basic Regular Expressions
        3. Awk 使用 Extended Regular Expressions
        4. 如果您想编写可移植脚本、makefile 等,您应该熟悉POSIX specifications,例如IEEE Std 1003.1

        我建议将表达式重写为

        's/\([a-zA-Z0-9.]\{1,\}\) [0-9] \(.*\)/\2 (\1)/g'
        

        在任何符合 POSIX 的sed 中,它应该完全符合您的要求。如果您确实关心这些事情,请考虑定义 POSIXLY_CORRECT 环境变量。

        【讨论】:

          【解决方案4】:
          $ sed -e 's/\([a-zA-Z0-9.].*\) [0-9] \(.*\)/\2 \(\1\)/g' file
          Doe, John (jdoe)
          Doe, Jane (jad)
          Smith, Jon (smith)
          

          【讨论】:

            【解决方案5】:

            使用 awk 要简单得多...:

            cat test.txt | awk '{ print $3 " " $4 " " "("$1")" }'
            

            输出:

            Doe, John (jdoe)
            Doe, Jane (jad)
            Smith, Jon (smith)
            

            见 man awk 1

            【讨论】:

              猜你喜欢
              • 2019-07-28
              • 2019-09-17
              • 1970-01-01
              • 2010-11-19
              • 2015-01-17
              • 1970-01-01
              • 2014-04-27
              • 1970-01-01
              • 2019-11-15
              相关资源
              最近更新 更多