1

I have two XML file first one ~/tmp/test.xml second one /data/myuser/.mycontent/mytest.xml I want to add all of the content on the first XML file to line 35 in the second one. I tried the following but with no luck

sed -n '35,~/tmp/test.xml`' /data/myuser/.mycontent/mytest.xml

(cat /data/myuser/.mycontent/mytest.xml; echo) | sed '35r ~/tmp/test.xml'

ed -s ~/tmp/test.xml <<< $'35r /data/myuser/.mycontent/mytest.xml\nw'

Line 33 from second XML file line 34 is empty

#the following tags contain employee location

XML tag in the first XML file

<Location "/mylocation">
    first Address
    second Address

    Mylocation "XX/XX/XX/XX"
    Myphone "XXXXXXX"
</Location>

What did I do wrong, please advise .

Edit 1

first XML ~/tmp/test.xml file contain only

<Location "/mylocation">
    first Address
    second Address

    Mylocation "XX/XX/XX/XX"
    Myphone "XXXXXXX"
</Location>

second XML /data/myuser/.mycontent/mytest.xml contain:

NameVirtualHost *:XXXX
<VirtualHost  *:XXXX>

    ServerName AAAAAAAA

# Manager comment 1
# Manager comment 2
# Manager comment 3
#
DocumentRoot "/data/myuser/.mycontent/"

# support email xxxxx@yyyyy.com
# started at 2010
<employee /*>
        AllowOverride None
</employee>

<Location "/">
        mylocation
        Deny from all
</Location>

<Location "/icons/">
#        employee info
        my employee info
        Allow from all
</Location>

DavLockDB /tmp/${APACHE_HOSTNAME}.DavLock
DAVMinTimeout 5000
LimitXMLRequestBody 0

# This should be changed to whatever you set DocumentRoot to.

## I need to add new tags here ##
<Location "/employee1">
    first Address
    second Address

    Mylocation "XX/XX/XX/XX"
    Myphone "XXXXXXX"
</Location>

<Location "/employee2">
    first Address
    second Address

    Mylocation "XX/XX/XX/XX"
    Myphone "XXXXXXX"
</Location>
## more tags same as above
## then manager comment

Edit 2 second file /data/myuser/.mycontent/mytest.xml should be like:

 NameVirtualHost *:XXXX
    <VirtualHost  *:XXXX>

        ServerName AAAAAAAA

    # Manager comment 1
    # Manager comment 2
    # Manager comment 3
    #
    DocumentRoot "/data/myuser/.mycontent/"

    # support email xxxxx@yyyyy.com
    # started at 2010
    <employee /*>
            AllowOverride None
    </employee>

    <Location "/">
            mylocation
            Deny from all
    </Location>

    <Location "/icons/">
    #        employee info
            my employee info
            Allow from all
    </Location>

    DavLockDB /tmp/${APACHE_HOSTNAME}.DavLock
    DAVMinTimeout 5000
    LimitXMLRequestBody 0

    # This should be changed to whatever you set DocumentRoot to.

    ## I need to add new tags here ##
  ## this tag from first file   
  <Location "/mylocation">
        first Address
        second Address

        Mylocation "XX/XX/XX/XX"
        Myphone "XXXXXXX"
    </Location>

  ## edit end

    <Location "/employee1">
        first Address
        second Address

        Mylocation "XX/XX/XX/XX"
        Myphone "XXXXXXX"
    </Location>

    <Location "/employee2">
        first Address
        second Address

        Mylocation "XX/XX/XX/XX"
        Myphone "XXXXXXX"
    </Location>
    ## more tags same as above
    ## then manager comment

Note: ## this tag from first file and ## edit end to specify merge location location

  • Can you give XML samples from both files - the core problem is, XML isn't plain text, and if you treat it as if it is, you create brittle code. Using a parser is the answer - I can give you an example if you can post your XML. (And indicate which tag you want to insert your content into) – Sobrique Dec 28 '15 at 22:15
  • @Sobrique I added content of file one and some of the content of file two – Ahmad Abuhasna Dec 29 '15 at 8:13
  • That isn't XML, which changes the answer – Sobrique Dec 29 '15 at 8:23
  • @Sobrique the page is extension XML thats why I added its XML page. sorry if I added wrong info. – Ahmad Abuhasna Dec 29 '15 at 8:30
  • i dont understand this question - you want all of the content in file one on line 35 of file 2? so you want it flattened? Or you want all of the content prepended to line 35? Or you want it appended? Or do you want it joined such that the content from the first line of file 1 is appended to the tail of line 35 and all of the rest of lines in file1 then follow? – mikeserv Dec 29 '15 at 10:16
1

OK, so this isn't XML inserting into XML like I thought - if it was, the answer would be 'use a parser'. However it's not, you're just merging one text file into another.

So I would break out the perl as I so often do:

#!/usr/bin/env perl
use strict;
use warnings;

open ( my $insert, '<', '~/tmp/test.xml' ) or die $!;
open ( my $modify, '<', '/data/myuser/.mycontent/mytest.xml' ) or die $!; 
open ( my $output, '>', '/data/myuser/.mycontent/mytest.xml.new' ) or die $!; 

select $output; 
while ( <$modify> ) { 
   if ( $. == 32 ) { print <$insert>; }; 
   print; 
}

This should do the trick - if you're after a one liner, then it can be condensed down to:

perl -p -i.bak -e 'BEGIN { open ( $insert, "<", shift ) } if ( $. == 32 ) { print <$insert> }' ~/tmp/test.xml /data/myuser/.mycontent/mytest.xml

Note $. is perl for "current line number". You can apply a different sort of conditional if you prefer. Like whether a regex matches (which might be more appropriate, given config files tend to get lines inserted into them).

2

With GNU sed:

If you want to insert file1.xml in file2.xml at line 35 with a leading newline:

sed -e '34{p;g;r file1.xml' -e '}' file2.xml

If you want to edit file2.xml "in place" add sed's option -i.

  • this worked great for me but what if I don't want the leading new line? – Michael Tunnell Mar 6 at 19:17
  • @MichaelTunnell: sed -e 34{r file1.xml' -e '}' file2.xml – Cyrus Mar 6 at 19:22
  • Yep, that was it. I removed p;g; and added -i to the parameters and it works great. Thank you so much for the help and the incredibly fast response! :D – Michael Tunnell Mar 6 at 19:23
  • @MichaelTunnell: I've reduced it to the essential part: sed '34r file1.xml file2.xml – Cyrus Mar 6 at 19:25
  • that is essentially what I ended with, thank you for clarifying so I could confirm what I put was correct! – Michael Tunnell Mar 6 at 19:28
0

I think I understand the problem with you're attempting to do. It looks like you maybe want to insert your read file on an input cue. You say line 35, but if you do sed 35r\ file that will be appended to 35. It's hard to watch input for a cue before which you want to write output if you don't secure a lookahead. For example:

sed -e'$!N;/\n<Location "\/employee1">/r /tmp/file1' \
    -eP\;D </tmp/file2 | tail -n30

Now that scans input for the <Location /employee1> and inserts the content of file1 immediately before it once found.


DAVMinTimeout 5000
LimitXMLRequestBody 0

# This should be changed to whatever you set DocumentRoot to.

## I need to add new tags here ##
<Location "/mylocation">
    first Address
    second Address

    Mylocation "XX/XX/XX/XX"
    Myphone "XXXXXXX"
</Location>
<Location "/employee1">
    first Address
    second Address

    Mylocation "XX/XX/XX/XX"
    Myphone "XXXXXXX"
</Location>

<Location "/employee2">
    first Address
    second Address

    Mylocation "XX/XX/XX/XX"
    Myphone "XXXXXXX"
</Location>
## more tags same as above
## then manager comment

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.