31

How to insert a line into a file using sed before a pattern and after a line number? And how to use the same in shell script?

This inserts a line before every line with the pattern :

sed '/Sysadmin/i \ Linux Scripting' filename.txt

And this changes this using line number range :

sed '1,$ s/A/a/'

So now how to use these both (which I couldn't) to insert a line into a file using sed before a pattern and after a line number or another approach?

codeforester
  • 39,467
  • 16
  • 112
  • 140
Nohsib
  • 3,614
  • 14
  • 51
  • 63

5 Answers5

29

You can either write a sed script file and use:

sed -f sed.script file1 ...

Or you can use (multiple) -e 'command' options:

sed -e '/SysAdmin/i\
Linux Scripting' -e '1,$s/A/a/' file1 ...

If you want to append something after a line, then:

sed -e '234a\
Text to insert after line 234' file1 ...
Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
  • So Jonathan, if i have xml in this format :: How do i use sed to add a line "" before the tag? – Nohsib Jun 08 '11 at 21:41
  • i figured it out, thanks for the help: sed -i -e '8,$ s/<\/vendor>/testing/' -e '/testing/i\ ' -e '8,$ s/testing/<\/vendor>/' vendors1.xml – Nohsib Jun 08 '11 at 21:54
  • for me to get this to work in place, I had to do `sed -i '22a Text I Added at Line 22' test.txt` – james-see Oct 29 '17 at 21:46
  • @jamescampbell : that means you are using GNU `sed` and also means that you wanted to overwrite the original file. Those weren’t necessarily part of the original requirements. It’s not wrong; just (slightly) different. Using BSD `sed`, you’d need to use `-i ‘’` instead of just `-i`, you’d not be able to cheat on the POSIX spec and omit the backslash newline. – Jonathan Leffler Oct 29 '17 at 22:47
  • @JonathanLeffler thanks thats a great explanation and makes sense now. – james-see Oct 29 '17 at 23:12
9

I assume you want to insert the line before a pattern only if the current line number is greater than some value (i.e. if the pattern occurs before the line number, do nothing)

If you're not tied to sed:

awk -v lineno=$line -v patt="$pattern" -v text="$line_to_insert" '
    NR > lineno && $0 ~ patt {print text}
    {print}
' input > output
glenn jackman
  • 238,783
  • 38
  • 220
  • 352
  • +1: I wondered if that was how the question should be interpreted too, but gave the simpler answer which seems to have been helpful. It would be hard to achieve that effect in `sed` - probably not quite impossible, but involving nested commands, etc. – Jonathan Leffler Jun 09 '11 at 14:44
1

here is an example of how to insert a line before a line in a file:

example file test.txt :

hello line 1
hello line 2
hello line 3

script:

sed -n 'H;${x;s/^\n//;s/hello line 2/hello new line\n&/;p;}' test.txt > test.txt.2

output file test.txt.2

hello line 1
hello new line
hello line 2
hello line 3

NB! notice that the sed has as beginning a substitution of a newline to no space - this is necessary otherwise resulting file will have one empty line in the beginning

The script finds the line containing "hello line 2", it then inserts a new line above -- "hello new line"

explanation of sed commands:

sed -n:
suppress automatic printing of pattern space

H;${x;s/test/next/;p}

/<pattern>/  search for a <pattern>
${}  do this 'block' of code
H    put the pattern match in the hold space
s/   substitute test for next everywhere in the space
x    swap the hold with the pattern space
p    Print the current pattern hold space. 
serup
  • 3,676
  • 2
  • 30
  • 34
0

Simple? From line 12 to the end:

sed '12,$ s/.*Sysadmin.*/Linux Scripting\n&/' filename.txt
Walter A
  • 19,067
  • 2
  • 23
  • 43
  • 1
    That works OK with GNU `sed`; it does not work with all other variants. I specifically tested with the BSD/macOS variant of `sed` and it produces `Linux ScriptingnSysadmin` for example. I also tested the same script with GNU `sed` and it worked — all I changed was the path to the command executed. – Jonathan Leffler Jan 02 '19 at 23:25
  • @JonathanLeffler Thanks for the explantion. I now remember that I had problems with newlines on Solaris and AIX "long ago". – Walter A Jan 03 '19 at 09:40
0

Insert a line before matching line:

sed '/^line starts with.*/i insert this line before' filename.txt

Output:

insert this line before
line starts with

Insert a line after matching line:

sed '/^line starts with.*/a insert this line after' filename.txt

Output:

line starts with
insert this line after
computerist
  • 872
  • 8
  • 9