[英]Linux sed regex replace with capture groups
我有一个包含以下格式的目录条目的文件:
<item><ln></ln><fn>Some person</fn><ct>07123456789</ct><sd>37</sd><rt>1</rt><bw>1</bw></item>
我想使用sed
搜索<ct>
是 11 位数字和<bw>1</bw>
的任何地方。 我想像这样更改上面的行:
<item><ln></ln><fn>Some person</fn><ct>07123456789</ct><sd>37</sd><rt>1</rt><bw>0</bw></item>
(如果不是很明显我已经改变了<bw>
= 0)
我在sed
中尝试过以下操作,但不匹配:
sed -E 's/(.+<ct>\d{11}.+<bw>)1(<\/bw><\/item>)/\10\2/g' test-directory.xml
我究竟做错了什么?
您可以将此sed
与 2 个捕获组一起使用:
sed -E 's~(.*<ct>[0-9]{11}</ct>.*<bw>)1(</bw>.*)~\10\2~' file
<item><ln></ln><fn>Some person</fn><ct>07123456789</ct><sd>37</sd><rt>1</rt><bw>0</bw></item>
更多信息:
(.*<ct>[0-9]{11}</ct>.*<bw>)
:匹配并捕获后跟<ct>11-digits</ct>
后跟任何文本后跟<bw>
的任何文本<bw>
在捕获组 #11
:(</bw>.*)
:匹配</bw>
后跟捕获组 #2 中的任何内容 PS:这假设<ct>
标签出现在同一行中的<bw>
标签之前。 为了更好地控制 XML,最好使用 XML 解析器而不是 shell 实用程序。
如果<bw>
标签位置不固定,那么您可以使用这个sed
解决方案:
sed -E '\~<ct>[0-9]{11}</ct>~ s~(.*<bw>)1(</bw>.*)~\10\2~' file
使用awk
(如果您对它没问题),您可以尝试遵循 GNU awk
解决方案,该解决方案是在 GNU awk
中编写和测试的,并带有显示的示例。 简单的解释是,使用awk
程序的match
函数,其中使用正则表达式(.*<ct>[0-9]{11}<\/ct>.*<bw>)([0-9]+)(<\/bw>.*)
在其中创建 3 个捕获组(稍后使用)并根据捕获组编号存储这些值,它将在名为arr
的数组中创建项目索引。 完成后,只打印需要的部分(用 0 更改任何数字,在</bw>
之前)。
awk '
match($0,/(.*<ct>[0-9]{11}<\/ct>.*<bw>)([0-9]+)(<\/bw>.*)/,arr){
print arr[1]"0"arr[3]
}
' Input_file
这是上面显示的正则表达式的在线演示。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.