我有几千条这样的文字行:
go to <CITY>rome</CITY> <COUNTRY>italy</COUNTRY>
我想要的输出是替换从第一个标记词(罗马)到最后一个(意大利)的所有内容并放置标记:
go to <ADDRESS>rome italy</ADDRESS>
我可以匹配标记为的文本行部分:
<.*>
这将贪婪地选择第一个&lt;持续&gt;。我希望删除标签并将<ADDRESS>
和</ADDRESS>
放在匹配的部分周围。
可能的标签有:<STREETNUM>
,<STREET>
,<CITY>
,<STATE>
,<ZIP>
和<COUNTRY>
。这些标记的任何子集都可以按任何顺序出现。标签永远不会嵌套。
我搜索了SO并用谷歌搜索无济于事。也许我可以使用一个命名的捕获组,然后在其上应用搜索/替换正则表达式,但我不知道如何。任何帮助都会受到赞赏。
答案 0 :(得分:2)
此sed
行将执行此操作:
sed 's/<CITY>\(.*\)<\/CITY>.*<COUNTRY>\(.*\)<\/COUNTRY>/<ADDRESS>\1 \2<\/ADDRESS> /g'
例如:
sed 's/<CITY>\(.*\)<\/CITY>.*<COUNTRY>\(.*\)<\/COUNTRY>/<ADDRESS>\1 \2<\/ADDRESS> /g' <<< "go to <CITY>rome</CITY> <COUNTRY>italy</COUNTRY>"
打印:
go to <ADDRESS>rome italy</ADDRESS>
它基本上捕获CITY
标记内和COUNTRY
标记内的内容,然后将其替换为包含ADDRESS
标记的捕获组值
如果您正在使用Linux,则可以避免使用(
标记转义-E
:
sed -E 's/<CITY>(.*)<\/CITY>.*<COUNTRY>(.*)<\/COUNTRY>/<ADDRESS>\1 \2<\/ADDRESS> /g'
<强>更新强>
为了达到预期的效果,您可以按以下操作顺序使用多个命令:
go to
文字:sed 's/go to //g'
tr -d '</>'
删除所有标记字符后,您可以安全地删除字词STREETNUM
,STREET
,CITY
,STATE
,ZIP
和{ {1}}来自输入:
COUNTRY
获取先前命令连接生成的输出并将其输出到sed -E 's/CITY|COUNTRY|STATE|ZIP|STREETNUM|STREET//g'
标记内:
<ADDRESS></ADDRESS>
最后的命令如下,xargs -i echo "go to <ADDRESS>{}</ADDRESS>"
应该包含要处理的行:
$LINE
一个例子:
运行:
sed 's/go to //g' <<< "$LINE" | tr -d '</>' | sed -E 's/CITY|COUNTRY|STATE|ZIP|STREETNUM|STREET//g' | xargs -i echo "go to <ADDRESS>{}</ADDRESS>"
将打印:
sed 's/go to //g' <<< "go to <STATE>Bolivar</STATE> <COUNTRY>Venezuela</COUNTRY> <STREETNUM>5</STREETNUM> " | tr -d '</>' | sed -E 's/CITY|COUNTRY|STATE|ZIP|STREETNUM|STREET//g' | xargs -i echo "go to <ADDRESS>{}</ADDRESS>"