sed to insert on first match only

You can sort of do this in GNU sed:

sed '0,/Matched Keyword/s//New Inserted Line\n&/'

But it's not portable. Since portability is good, here it is in awk:

awk '/Matched Keyword/ && !x {print "Text line to insert"; x=1} 1' inputFile

Or, if you want to pass a variable to print:

awk -v "var=$var" '/Matched Keyword/ && !x {print var; x=1} 1' inputFile

These both insert the text line before the first occurrence of the keyword, on a line by itself, per your example.

Remember that with both sed and awk, the matched keyword is a regular expression, not just a keyword.

UPDATE:

Since this question is also tagged bash, here's a simple solution that is pure bash and doesn't required sed:

#!/bin/bash

n=0
while read line; do
  if [[ "$line" =~ 'Matched Keyword' && $n = 0 ]]; then
    echo "New Inserted Line"
    n=1
  fi
  echo "$line"
done

As it stands, this as a pipe. You can easily wrap it in something that acts on files instead.


If you want one with sed*:

sed '0,/Matched Keyword/s//Matched Keyword\nNew Inserted Line/' myfile.txt

*only works with GNU sed


This might work for you:

sed -i -e '/Matched Keyword/{i\New Inserted Line' -e ':a;n;ba}' file

You're nearly there! Just create a loop to read from the Matched Keyword to the end of the file.

After inserting a line, the remainder of the file can be printed out by:

  1. Introducing a loop place holder :a (here a is an arbitrary name).
  2. Print the current line and fetch the next into the pattern space with the ncommand.
  3. Redirect control back using the ba command which is essentially a goto to the a place holder. The end-of-file condition is naturally taken care of by the n command which terminates any further sed commands if it tries to read passed the end-of-file.

With a little help from bash, a true one liner can be achieved:

sed $'/Matched Keyword/{iNew Inserted Line\n:a;n;ba}' file

Alternative:

sed 'x;/./{x;b};x;/Matched Keyword/h;//iNew Inserted Line' file

This uses the Matched Keyword as a flag in the hold space and once it has been set any processing is curtailed by bailing out immediately.

Tags:

Linux

Bash

Sed