我需要修复错误,并在XML文件中用</time>
替换第二个标记</tags>
,其结构如下:
<time>20260664</time>
<tags>substancesummit ss</time>
<geo>asdsadsa</geo>
<time>20260664</time>
<tags>substancesummit ss</time>
<geo>asdsadsa</geo>
我正在尝试使用sed,因为每个项目有2个</time>
结束标记,我的想法是将</time><geo>
替换为</tags><geo>
。
但是中间有一个下一行符号,所以我使用的是\n
,但它不起作用:
sed 's/time>\n<geo>/tags>\n<geo>/g' old.xml > new.xml
任何帮助?
答案 0 :(得分:1)
您可以在1个单独的sed命令中执行此操作:
sed '/<\/time>/I{n;:A;N;h;/<geo>/I!{H;bA};/<geo>/I{g;s/<\/time>/<\/tags>/i}}' file.txt
如果输入的file.txt是这样的:
<time>20260664</time>
<tags>substancesummit ss
</time>
<Geo>asdsadsa</geo>
<time>30260664</time>
<tags>substancesummit st</timE>
<geo>bsdsadsa</geo>
然后上述命令的输出将是:
<time>20260664</time>
<tags>substancesummit ss
</tags>
<Geo>asdsadsa</geo>
<time>30260664</time>
<tags>substancesummit st</tags>
<geo>bsdsadsa</geo>
它涵盖了\r
和\n
</time>
或<geo>
)
PS:上面的sed命令正在忽略关注搜索/替换,如果你不想这样,那么只需从sed命令中删除I
标志或者告诉我。
答案 1 :(得分:1)
使用此:
$ sed -n '1h; 1!H; $ {g; s/<\/time>\n<geo>/<\/tags>\n<geo>/g; p;}' file
答案 2 :(得分:1)
如果有一个你肯定不会在文件中使用的字符,请尝试用它替换\ n,执行sed工作并替换回来。 tr非常适合那个
cat old.txt | tr '\n' '#' | sed 's/time>#<geo>/tags>#<geo>/g' | tr '#' '\n' > new.txt
我使用#作为替换字符。
答案 3 :(得分:0)
sed通常会编辑行,而且让它一次理解多行是有点困难的。相反,如何更直接地修复断线,如下所示:
/<tags>/ s@</time>@</tags>@
这将仅在</time>
的{{1}}行替换</tags>
。请注意,我使用<tags>
而不是@
作为替换命令的分隔符,以避免需要转义我们尝试替换的XML中的斜杠。
答案 4 :(得分:0)
您可以使用awk
代替
$ awk -vRS="</geo>" '{gsub(/<\/time>.<geo>/,"</tags>\n<geo>")}1' ORS="</geo>" file
<time>20260664</time>
<tags>substancesummit ss</tags>
<geo>asdsadsa</geo>
<time>20260664</time>
<tags>substancesummit ss</tags>
<geo>asdsadsa</geo>
首先,我可以看到</geo>
结束每个块,因此将其设为记录分隔符。之后,替换所需的内容。最后,将</geo>
作为输出记录分隔符(ORS)。
答案 5 :(得分:0)
为什么不回避尝试匹配换行符的问题,而是尝试将该行与开头<tags>
标记匹配,并将其后的内容与(非)匹配</time>
进行匹配标签?喜欢
# untested, written from scratch
sed 's/<tags>(.*)<\/time>/<tags>\1<\/tags>/g' infile > outfile
答案 6 :(得分:0)
sed -e 's,<\([^>]*\)>\([^<]*\)</[^>]*>,<\1>\2</\1>,g' tags.xml
这取代了同一行
(opening tag)(content)(closing tag)
带
(opening tag)(content)(closing tag)
但结束标记始终与开始标记相同。
如果在文件中找到多个标记对,则可能会失败。
详细信息,它搜索某些内容,以“&lt;”开头,后跟标记名称而不关闭“&gt;”,然后搜索内容,直到“&lt;”为止。