2

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>
  • 4
    You understand that this leaves you with an xml file that is syntactically incorrect, i.e. you're missing the closing </Networks> tag by removing the line. – wurtel Mar 16 '15 at 10:45
  • yes I know that ( the first Networks exist on the top of the file – maihabunash Mar 16 '15 at 10:46
  • 2
    Why do you need an ill formed XML file? – choroba Mar 16 '15 at 10:47
  • dont worry later I will append new lines that will be in place that line – maihabunash Mar 16 '15 at 10:49
  • 4
    Looks like an XY problem to me. What are you -actually- trying to accomplish? Parsing XML with regex is a bad idea, because there's lots of ways it can go wrong. Creating malformed XML deliberately is also a bad idea, for much the same reason. What problem are you trying to solve? I will probably suggest the answer is - use an XML parser, not a regex. With a bit more XML as a sample, this is actually very easy to do. – Sobrique Mar 16 '15 at 11:11
3

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.

  • I'll now leave you to be partonised by the regulars: if you're an expert, you already know the issues, and if not you will learn them by trying this. – Dan Sheppard Mar 16 '15 at 11:40
  • the units line is only the one unit line in the XML so I not see any problem here – maihabunash Mar 16 '15 at 12:04
4

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;
0

Since you indicate that you are aware that this will break your XML, you can do what you want with one of these:

  1. Perl

    perl -ne 'print unless m#^<units>.*</Networks>$#' file.xml 
    perl -ne 'm#^<units>.*</Networks>$# ? next : print' file.xml 
    
  2. awk

    awk '!/^<units>.*<\/Networks>$/' file.xml 
    
  3. sed

    sed '/^<units>.*<\/Networks>$/d' file.xml 
    
  4. grep

    grep -Ev '^<units>.*<\/Networks>$' file.xml 
    
  5. Bash (and zsh), for the sake of completion

    while read -r line; do 
        [[ "$line" =~ ^\<units\>.*\<\/Networks\>$ ]] || printf "%s\n" "$line"
    done < file.xml 
    
  • The awk one is a really (no pun intended) awkward way of doing it. Why not awk '!/<units>.*<\/Networks>/' – user78605 Mar 16 '15 at 13:56
  • You need the ! before it or else it will only print that line – user78605 Mar 16 '15 at 14:43
  • @JID fixed, I wrote too fast – terdon Mar 16 '15 at 14:49
  • Sorry, you are also missing the last / :( – user78605 Mar 16 '15 at 15:09
  • 1
    @JID yes, that's what I get for editing on my phone. Thanks. Next time though, please edit the post directly to fix this sort of thing. – terdon Mar 16 '15 at 15:15

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.