正确转义sed字符串

时间:2010-01-16 00:29:34

标签: bash sed escaping

我有一个正则表达式和替换模式,它们都在我的输入数据上使用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

如何才能正确转义?

5 个答案:

答案 0 :(得分:17)

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

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

答案 1 :(得分:9)

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

  1. -r选项是GNU扩展,用于启用扩展正则表达式。 BSD派生sed使用-E代替。
  2. SedGrep使用Basic Regular Expressions
  3. Awk使用Extended Regular Expressions
  4. 如果您想编写可移植脚本,makefile等,您应该对POSIX specifications感到满意,例如IEEE Std 1003.1
  5. 我建议将表达式重写为

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

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

答案 2 :(得分:4)

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

答案 3 :(得分:2)

使用awk更简单......:

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

输出:

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

见man awk 1

答案 4 :(得分:1)

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