sed:在后向引用中执行替换

时间:2015-05-22 08:21:26

标签: regex sed

我使用以下行生成HTML列表的一部分:

sed -r 's|(.*dn=([^&]+).*)|<li><a href="\1">\2</a></li>|' file.txt

我想要执行更多替换,但仅限于\2反向引用,而不是整行。这有可能,怎么样?

2 个答案:

答案 0 :(得分:3)

使用sed可以这样做:

sed -r 'h; s|(.*dn=([^&]+).*)|<li><a href="\1">\n</a></li>|; x; s//\2/; s/foo/bar/; G; s/(.*)\n(.*)\n(.*)/\2\1\3/' filename

那是:

#!/bin/sed -rf

h                                                 # copy line to hold buffer

s|(.*dn=([^&]+).*)|<li><a href="\1">\n</a></li>|  # generate the outer parts of
                                                  # the wanted result, with a
                                                  # newline where \2 will go
                                                  # when it was edited

x                                                 # exchange hold buffer and
                                                  # pattern space to bring back
                                                  # the input line

s//\2/                                            # isolate \2 (// reattempts the
                                                  # previous regex)

s/foo/bar/                                        # your substitutions here

G                                                 # append hold buffer to pattern
                                                  # space

s/(.*)\n(.*)\n(.*)/\2\1\3/                        # rearrange the parts in the
                                                  # desired order.

给出输入

http://www.example.com/website.html?a=b&dn=foo&asd=fgh

这将生成

<li><a href="http://www.example.com/website.html?a=b&dn=foo&asd=fgh">bar</a></li>

旁注:由于您的\1是完整匹配,因此在替换第一个&命令时使用s可能会更好一些,即

#                             v-- here
s|.*dn=([^&]+).*|<li><a href="&">\n</a></li>|

在上面的解决方案中,这样做需要s//\1/而不是s//\2,因为捕获组现在是\1

答案 1 :(得分:-1)

使用@ Wintermute的示例输入:

http://www.example.com/website.html?a=b&dn=foo&asd=fgh

和GNU awk为第3个arg匹配()来保存数组中的捕获组:

$ awk 'match($0,/(.*dn=([^&]+).*)/,a) { $0="<li><a href=\"" a[1] "\">" a[2] "</a></li>"} 1' file
<li><a href="http://www.example.com/website.html?a=b&dn=foo&asd=fgh">foo</a></li>

$ awk 'match($0,/(.*dn=([^&]+).*)/,a) { sub(/foo/,"bar",a[2]); $0="<li><a href=\"" a[1] "\">" a[2] "</a></li>"} 1' file
<li><a href="http://www.example.com/website.html?a=b&dn=foo&asd=fgh">bar</a></li>

只需将sub(/foo/,"bar",a[2])替换为您真正想要使用第二个捕获组的任何内容。