就地执行的sed命令无法正常工作。

4

我经常使用GNU Sed工具在进行原地替换时遇到一些问题。这次,我尝试从类似以下xml条目中删除一些逗号:

<address>T/A Business Name, 74, Address Line 1, Some Town, Some City</address>

...特别是地址数字后面的逗号(例如74后面的逗号)需要被移除。因此我使用类似以下的方式:

sed -nr 's!(<address>T/A\s+.*?,\s*[0-9]+\s*),(.*</address>)!\1\2! p'

这将按照我所期望的方式打印出将要更改的行,即删除地址编号后面的逗号。但当我更改命令以实际对文件进行就地更改时,如下所示:

sed -ir 's!\(<address>T/A\s+.*?,\s*[0-9]+\s*\),\(.*</address>\)!\1\2!'

但是这个命令没有任何作用。除了我必须在这次转义捕获括号,否则每个匹配的行都会出现错误,但它是完全相同的命令:

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

根据您的环境,您可能需要在“-i”选项后指定备份文件名。请查看手册以获取更多信息... - jahroy
2个回答

7
你也可以尝试这个,
sed -ri 's~^(.*Name, [0-9]+),(.*)$~\1\2~g' file

不要在sed命令中在-r之前使用-i选项,否则会显示像上面那样的错误消息。
示例:
$ cat aa
<address>T/A Business Name, 74, Address Line 1, Some Town, Some City</address>

$ sed -r 's~^(.*Name, [0-9]+),(.*)$~\1\2~g' aa
<address>T/A Business Name, 74 Address Line 1, Some Town, Some City</address>

啊,原来如此,我得到了生成了重复文件*.xmlr - 我之前没有注意到。 - RTF
1
我只是想解释一下为什么如果你使用“-ir”(i在r之前)就不起作用。 - jahroy
因为sed中的r标志意味着扩展正则表达式,从而有助于解析输入文件。在解析完毕后,就会进行编辑部分。因此,在使用i之前必须先使用r - Avinash Raj
2
所以再重申一下,我必须转义括号以进行原地版本,因为我没有使用任何扩展正则表达式标志 - 它被解释为 -i 标志的参数(备份文件 - 这就解释了所有生成的 .xmlr 文件)。谢谢大家。 - RTF

3

对于一些版本的sed工具,当使用-i选项进行就地编辑时,需要指定备份后缀。

在其他版本的sed中,备份后缀是可选的。

在你的情况下,r被解释为备份后缀(因为它紧随着i选项之后)。

根据我系统上的sed手册(Ubuntu 12.04):

       -i[SUFFIX], --in-place[=SUFFIX]

          edit files in place (makes backup if extension supplied)

使用方法:

sed -i.bak "s/this/that/g" input.txt

这将导致两件事发生:

  1. sed将会就地修改input.txt文件
  2. input.txt.bak将被创建为备份文件

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