如何仅从 xml 文件中删除行(使用 sed/awk 或 perl 一行)
开头为:
<units>
并结束于
</Networks>
如下
<units><unit ip= ............ </units><ranges/></Networks>
答案1
不要使用正则表达式来解析 XML。这是创建脆弱代码的绝佳方法,因为您可以使用 XML 执行许多完全有效的操作,而这些操作会破坏正则表达式。以完全有效的方式重新格式化 XML(例如以嵌套/缩进形式“漂亮地打印”它)之类的事情会破坏您的代码。
相反,我建议使用 XML 解析器。就我个人而言,我喜欢XML::Twig
Perl 中的模块。
您的评论表明您正在尝试向<Networks>
XML 中的元素添加内容。
那么像这样的事情怎么样:
#!/usr/bin/perl
use strict;
use warnings;
use XML::Twig;
my $xml_text = '<XML>
<Networks><units><unit ip="1.2.3.4" /></units><ranges/></Networks>
</XML>';
my $parser = XML::Twig->new( 'pretty_print' => 'indented' );
#would probably use 'parsefile' instead here
$parser->parse($xml_text);
print "\nBefore:\n";
$parser->print;
#insert a new element into 'Networks':
$parser->root->first_child('Networks')->insert_new_elt(
'last_child', #position - end of "Networks" element
'new_element', #element
{ 'attribute_here' => "value_here",
'another_attribute' => 'another_value',
}, #attributes as key value pairs
"Content_here", #element content
);
print "\nAfter:\n";
$parser->print;
答案2
尝试这个:
perl -i -pe 's|^<units>.*</Networks>$||' /my/filename
请注意,如果行中有前导或尾随空格,则需要这样:
perl -i -pe 's|^ *<units>.*</Networks> *$||' /my/filename
我使用管道作为分隔符而不是斜杠,以避免不必要的转义。
答案3
由于您表明您知道这会破坏您的 XML,因此您可以使用以下之一执行您想要的操作:
珀尔
perl -ne 'print unless m#^<units>.*</Networks>$#' file.xml perl -ne 'm#^<units>.*</Networks>$# ? next : print' file.xml
awk
awk '!/^<units>.*<\/Networks>$/' file.xml
sed
sed '/^<units>.*<\/Networks>$/d' file.xml
grep
grep -Ev '^<units>.*<\/Networks>$' file.xml
Bash(和 zsh),为了完成
while read -r line; do [[ "$line" =~ ^\<units\>.*\<\/Networks\>$ ]] || printf "%s\n" "$line" done < file.xml