正确转义 sed 字符串

10

我有一个正则表达式和替换模式,它们在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个回答

17

通常我觉得使用-r选项更容易,因为这意味着转义字符与大多数其他编程语言的转义字符类似:

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

9
一些警告和补充,需要注意之前其他人已经提到的内容:
  1. -r选项是GNU扩展,用于启用扩展的正则表达式。BSD衍生的sed使用-E
  2. SedGrep使用基本正则表达式
  3. Awk使用扩展正则表达式
  4. 如果您想编写可移植的脚本、makefile等,应熟悉POSIX规范,如IEEE Std 1003.1
我建议将表达式重写为
's/\([a-zA-Z0-9.]\{1,\}\) [0-9] \(.*\)/\2 (\1)/g'

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


4

如果不使用-r开关,加号需要进行转义。


2

使用awk要简单得多...

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

输出:

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

请查看awk的手册1

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接