how to delete only the line from xml file ( with sed/awk or perl one liner line )
that start with:
<units>
and ended with
</Networks>
as the follwoing
<units><unit ip= ............ </units><ranges/></Networks>
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. It only takes a minute to sign up.
Sign up to join this communityhow to delete only the line from xml file ( with sed/awk or perl one liner line )
that start with:
<units>
and ended with
</Networks>
as the follwoing
<units><unit ip= ............ </units><ranges/></Networks>
Do not use regular expressions to parse XML. It's an excellent way to create brittle code, because there's a bunch of perfectly valid things you can do with XML which will break a regex. Things like reformatting the XML in entirely valid ways (such as 'pretty printing' it in a nested/indented form) will break your code.
Instead I would suggest - use an XML parser. Personally, I like the XML::Twig
module in perl.
Your comment suggests that what you're trying to do is add stuff to a <Networks>
element in your XML.
So how about something like this:
#!/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;
Try this:
perl -i -pe 's|^<units>.*</Networks>$||' /my/filename
Note that if you have leading or trailing space in the line you will need this instead:
perl -i -pe 's|^ *<units>.*</Networks> *$||' /my/filename
I uesd pipe as a separator rather than slash to avoid unnecessary escaping.
Since you indicate that you are aware that this will break your XML, you can do what you want with one of these:
Perl
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 (and zsh), for the sake of completion
while read -r line; do
[[ "$line" =~ ^\<units\>.*\<\/Networks\>$ ]] || printf "%s\n" "$line"
done < file.xml
awk '!/<units>.*<\/Networks>/'
!
before it or else it will only print that line
/
:(
</Networks>
tag by removing the line.