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)
    – Sobrique
    CommentedDec 28, 2015 at 22:15
  • @Sobrique I added content of file one and some of the content of file twoCommentedDec 29, 2015 at 8:13
  • 1
    That isn't XML, which changes the answer
    – Sobrique
    CommentedDec 29, 2015 at 8:23
  • @Sobrique the page is extension XML thats why I added its XML page. sorry if I added wrong info.CommentedDec 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?
    – mikeserv
    CommentedDec 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?CommentedMar 6, 2019 at 19:17
  • @MichaelTunnell: sed -e 34{r file1.xml' -e '}' file2.xml
    – Cyrus
    CommentedMar 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! :DCommentedMar 6, 2019 at 19:23
  • @MichaelTunnell: I've reduced it to the essential part: sed '34r file1.xml file2.xml
    – Cyrus
    CommentedMar 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!CommentedMar 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.