3

I want to append 'maildomain' after the line port in a php file. I really want to use this solution as this seems the cleanest and very clear so I did

sed -i "350,/port/a \'maildomain\'" file.php

but it came out like this :

351 : 'maildomain'
352 : 
353 : 'maildomain'
354 : 
...
358 : blablabla port blabla
359 : 'maildomain'

As you can see, it adds 'maildomain' alternately from line 350 until it found port which is located at line 354 initially. How do I modify the sed command above to just add 'maildomain' after port and not before it? Thank you.

Also, when use line 353 instead of 350, it gives me this :

353 : 'maildomain'
354 : balsdbflasdbflsd port blablablabla
355 : 'maildomain'

Why? Thanks~

Community
  • 1
  • 1
John Evans Solachuk
  • 1,953
  • 5
  • 31
  • 67

3 Answers3

5

An address of the form x,y means all the lines from x through y inclusive, so 350,/port/ means each line from 350 through the line that matches the /port/ regexp.

If you only want to append after the /port/ line, just specify that address:

sed -i "/port/a \'maildomain\'" file.php
hwnd
  • 69,796
  • 4
  • 95
  • 132
Barmar
  • 741,623
  • 53
  • 500
  • 612
  • Thanks for the explanation but I also want to start replacing only the first matched word after line 350 because I have many other words `port` in my file. How do I do that? Thanks! – John Evans Solachuk May 28 '14 at 06:08
3

If you wish to add 'maildomain' after any line that contains port then Barmar has the right answer. However, if you have many such lines that contains port and only wish to add after line number 350 then you can do the following:

sed -i "350,/port/{
    /port/a \'maildomain\'
}" file.php

This will look for lines after line number 350 and any line that has port in it, it will append 'maildomain' after it. Notice how I have split the command on multiple lines. You need to do that as well. It is due to the fact that the a command in sed requires an actual newline character.

If you only wish to add it once after line number 350 then you can branch out b after you are done adding.

sed -i "350,/port/{
    /port/a \'maildomain\'
    b;
}" file.php
Community
  • 1
  • 1
jaypal singh
  • 74,723
  • 23
  • 102
  • 147
  • 1
    Lol I just commented on Barmar's answer before I saw this. Your answer is what I wanted but I got this error : `sed: -e expression #1, char 0: unmatched `{'` when I tried to compact it to one line and run it. I really need to compact it because I'm planning to use it in my C code, not in a shell script. How do I compact it? Thank you! – John Evans Solachuk May 28 '14 at 05:56
  • 1
    @user3526156 Ok, try `sed "350,/port/{/port/N;s/\n/\nmaildomain\n/}" file.php`. This should work for your case. – jaypal singh May 28 '14 at 06:31
  • 1
    Thanks for being patient with me! Saved my hair. ;) – John Evans Solachuk May 28 '14 at 06:36
0

If I'm understanding your requirements properly, you can do this in sed using Barmar's solution.

Or you could use awk:

awk '1;/port/{print "maildomain"}'

This prints the current line, and then tests to see if the current line includes your keyword, and if it does, prints the extra line.

Or, since you've mentioned the bash tag, you could do this in pure bash:

while read line; do echo "$line"; [[ $line =~ port ]] && echo "maildomain"; done

This implements exactly the same logic as the awk solution, but without launching an external interpreter.

ghoti
  • 45,319
  • 8
  • 65
  • 104