3

Using a bash script, I am trying to insert a line in a file (eventually there will be 4 extra lines, one after the other).

I am trying to implement the answer by iiSeymour to the thread:

Insert lines in a file starting from a specific line

which I think is the same comment that dgibbs made in his own thread:

Bash: Inserting a line in a file at a specific location

The line after which I want to insert the new text is very long, so I save it in a variable first:

field1=$(head -2 file847script0.xml | tail -1)

The text I want to insert is:

insert='newtext123'

When running:

sed -i".bak" "s/$field1/$field1\n$insert/" file847script0.xml 

I get the error:

sed: 1: "s/<ImageAnnotation xmln ...": bad flag in substitute command: 'c'

I also tried following the thread

sed throws 'bad flag in substitute command'

but the command

sed -i".bak" "s/\/$field1/$field1\n$insert/" file847script0.xml

still gives me the same error:

sed: 1: "s/\/<ImageAnnotation xm ...": bad flag in substitute command: 'c'

I am using a Mac OS X 10.5.

Any idea of what am I doing wrong? Thank you!

Community
  • 1
  • 1
user3570398
  • 345
  • 2
  • 5
  • 14
  • I suspect the inserted field text is breaking the sed pattern matching syntax, if there is a "/" in it (as well there might be if it's HTML) then it will break. You could try another pattern matching character, eg: `sed "s|$field...|..." ...` – nic ferrier Jul 14 '14 at 20:41
  • The command sed -i".bak" "s|$field1|$field1\n$insert|" file847script0.xml inserts the line but doesn't recognize \n as a new line. How can I solve it? thanks! – user3570398 Jul 14 '14 at 21:05

2 Answers2

2

Good grief, just use awk. No need to worry about special characters in your replacement text or random single-character commands and punctuation.

In this case it looks like all you need is to print some new text after the 2nd line so that's just:

$ cat file
a
b
c

$ insert='absolutely any text you want, including newlines
slashes (/), backslashes (\\), whatever...'

$ awk -v insert="$insert" '{print} NR==2{print insert}' file
a
b
absolutely any text you want, including newlines
slashes (/), backslashes (\), whatever...
c
Ed Morton
  • 188,023
  • 17
  • 78
  • 185
0

Isn't it easier to do it by line number? If you know it's the second line or the nth line (and grep will tell you line numbers if you are pattern matching) then you can simply use sed to find the correct line and then append a new line (or 4 new lines).

cat <<EOF > testfile
one two three
four five six
seven eight nine
EOF

sed -re '2a\hello there' testfile

will output

one two three
four five six
hello there
seven eight nine
Barmar
  • 741,623
  • 53
  • 500
  • 612
nic ferrier
  • 1,573
  • 13
  • 14
  • I actually managed to insert a new line at a specific line but it would not "push" the whole text down. I would get the new text and then the old text in the same line. – user3570398 Jul 14 '14 at 20:34
  • well, I managed it. I guess you were using the "i" command in sed and not the "a" command? The sed on OSX is not quite the same as GNU sed which is normally what Linux machines have installed. Maybe there's a difference. I don't have OSX to hand to test. – nic ferrier Jul 14 '14 at 20:38
  • I was actually using sed -i".bak" '3a\ new line' file.xml. I tried your answer but the -re option is "illegal". I see; yes, I'm learning is not the same.. Thanks! – user3570398 Jul 14 '14 at 20:41
  • maybe this is a difference with OSX's sed... you could try: ```` sed '3a\ new line' file.xml ```` -- with a carriage return after the `3a\` – nic ferrier Jul 14 '14 at 20:42
  • Yes, that's what I tried and worked; i.e.: inserted the text, but in lines where there was text previously the inserted text was just before the old text... Thanks again! – user3570398 Jul 14 '14 at 20:46