1

I have a file with many lines but I can summarise my requirements like below:

            <DT><A HREF="http://127.0.0.1:1234/ABCDE/wp-admin/index.cfm?event&msg=secure&fr=sp">Wonderland(Site 3)</A>
            <DT><A HREF="http://127.0.0.1:5678/FGHIJ/wp-admin/index.cfm?event&msg=secure&fr=sp">abc (test)</A>
--
            <DT><A HREF="http://127.0.0.1:1234/ABCDE/wp-admin/index.cfm?event&msg=secure&fr=sp">Wonderland(Site 3)</A>
            <DT><A HREF="http://127.0.0.1:8303/CFIDE/administrator/index.cfm?event&msg=secure&fr=sp">xyz (Prod)</A>
--
            <DT><A HREF="http://127.0.0.1:1234/ABCDE/wp-admin/index.cfm?event&msg=secure&fr=sp">Wonderland(Site 3)</A>
            <DT><A HREF="http://127.0.0.1:8303/CFIDE/administrator/index.cfm?event&msg=secure&fr=sp">lmn (Prod)</A>

I have to insert a new line after first occurrence of:

<DT><A HREF="http://127.0.0.1:1234/ABCDE/wp-admin/index.cfm?event&msg=secure&fr=sp">Wonderland(Site 3)</A>

similar to it e.g.

<DT><A HREF="http://127.0.0.1:2323/xnmp/wp-admin/index.cfm?event&msg=secure&fr=sp">NewSite(Site 4)</A>

insert a new line after second occurrence with another variable line similar to above and so does after third line match.

I have tried something like this with various combinations but it is not working:

input1='<DT><A HREF="http://127.0.0.1:1234/ABCDE/wp-admin/index.cfm?event&msg=secure&fr=sp">Wonderland(Site 3)</A>
output1='<DT><A HREF="http://127.0.0.1:2323/xnmp/wp-admin/index.cfm?event&msg=secure&fr=sp">NewSite(Site 4)</A>'
output2='<DT><A HREF="http://127.0.0.1:2324/xnmp/wp-admin/index.cfm?event&msg=secure&fr=sp">NewSite(Site 4)</A>'
output3='<DT><A HREF="http://127.0.0.1:2124/xnmp/wp-admin/index.cfm?event&msg=secure&fr=sp">NewSite(Site 4)</A>'
gawk -i inplace -v in2="$input1" -v voutput1="$output1" '/in2/{c++;if(c==1){sub(in2,in2 "\n" voutput3);c=0}}1' a  ; where a is my file name

I am able to replace all using sed but not individually. Working one which replaces all:

sed -i.bak "s#$input1#$input1\n\t\t$output1#" a

Expected output:

            <DT><A HREF="http://127.0.0.1:1234/ABCDE/wp-admin/index.cfm?event&msg=secure&fr=sp">Wonderland(Site 3)</A>
            <DT><A HREF="http://127.0.0.1:2323/xnmp/wp-admin/index.cfm?event&msg=secure&fr=sp">NewSite(Site 4)</A>
            <DT><A HREF="http://127.0.0.1:5678/FGHIJ/wp-admin/index.cfm?event&msg=secure&fr=sp">abc (test)</A>
--
            <DT><A HREF="http://127.0.0.1:1234/ABCDE/wp-admin/index.cfm?event&msg=secure&fr=sp">Wonderland(Site 3)</A>
            <DT><A HREF="http://127.0.0.1:2324/xnmp/wp-admin/index.cfm?event&msg=secure&fr=sp">NewSite(Site 4)</A>
            <DT><A HREF="http://127.0.0.1:8303/CFIDE/administrator/index.cfm?event&msg=secure&fr=sp">xyz (Prod)</A>
--
            <DT><A HREF="http://127.0.0.1:1234/ABCDE/wp-admin/index.cfm?event&msg=secure&fr=sp">Wonderland(Site 3)</A>
            <DT><A HREF="http://127.0.0.1:2124/xnmp/wp-admin/index.cfm?event&msg=secure&fr=sp">NewSite(Site 4)</A>
            <DT><A HREF="http://127.0.0.1:8303/CFIDE/administrator/index.cfm?event&msg=secure&fr=sp">lmn (Prod)</A>
  • It will be good if you also provide the expected output. It is not very clear from the problem description what it is that you want. – Rakesh Sharma Oct 23 at 4:59
0

Instead of storing in variables, put all the outputs, one per line, in a file, say outf Then do this:

$ sed -e "\\#${input1}#R outf" a

This assumes you are using GNU sed. Once you are satisfied of the changes, then bring in the -i option.

Explanation:

° Alternate delimiter needs to escaped by a backslash. In our case, # is the delimiter, so we escape it with a backslash.
° Wait a minute but I see two of them here, you'll be asking. Well coz, before what we write on the command line gets to sed is seen n processed by the shell. So since backslash is special within double quotes, we need to double it so that after shell has seen it, it shall be presented as one to sed. So the Universe is happy.
° Now comes the R command. This is a nonstandard command given by Gnu folks,  and is precisely what the doctor ordered for your scenario. It will print one line each time it is invoked and place that line after the current input line is printed.

******** /Fini.

  • I redirected the three outputs to three files. Then did below: ' sed -i -e "\\#${input1}#R b01" a ; sed -i -e "\\#${input1}#R b02" a ; sed -i -e "\\#${input1}#R b03" a ; ' But it appended all three outputs after matching first input1 instead of output2 after second match and output3 after third match ; where b01,b02,b03 are my output files. – user8122451 Oct 30 at 0:01
  • You need to do as prescribed, and place all the output lines in the outf file.. And you don't run sed multiple times. – Rakesh Sharma Oct 30 at 0:04
  • Thanks a lot Rakesh. It worked. Can you please explain the syntax as well for my understanding. I was trying to find the answer for this for quiet some time now. You have really helped me a lot. Thanks. – user8122451 Oct 30 at 0:21
  • Added a brief description have a look. – Rakesh Sharma Oct 30 at 7:08

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.