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 [email protected]
# 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 [email protected]
    # 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

6
  • 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) Commented Dec 28, 2015 at 22:15
  • @Sobrique I added content of file one and some of the content of file two Commented Dec 29, 2015 at 8:13
  • 1
    That isn't XML, which changes the answer Commented Dec 29, 2015 at 8:23
  • @Sobrique the page is extension XML thats why I added its XML page. sorry if I added wrong info. Commented Dec 29, 2015 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? Commented Dec 29, 2015 at 10:16

3 Answers 3

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.

5
  • this worked great for me but what if I don't want the leading new line? Commented Mar 6, 2019 at 19:17
  • @MichaelTunnell: sed -e 34{r file1.xml' -e '}' file2.xml Commented Mar 6, 2019 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 Commented Mar 6, 2019 at 19:23
  • @MichaelTunnell: I've reduced it to the essential part: sed '34r file1.xml file2.xml Commented Mar 6, 2019 at 19:25
  • that is essentially what I ended with, thank you for clarifying so I could confirm what I put was correct! Commented Mar 6, 2019 at 19:28
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).

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

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.