Sed to Insert on First Match Only

sed to insert on first match only

If you want one with sed*:

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

*only works with GNU sed

Append a line after the first match only using sed

This might work for you (GNU sed):

sed '0,/orange/!b;//a\pear' file

Focus on the range of lines from the start of the file 0 to the first occurrence of the string orange otherwise bail out. If the line contains the first occurrence of the string orange, append the string pear.

sed to insert a text line after first match only & remove n lines after second match using sed only

This might work for you (GNU sed):

sed -e '/B/!b;x;s/^/x/;/^x\{1\}$/{x;aE' -e 'b};x' file

sed -e '/B/!b;x;s/^/x/;/^x\{2\}$/{x;n;N;d};x' file

Both these solutions can be split into three parts:

  • Focus on a particuar regexp
  • Counting
  • Conditional on the above

If the regexp is not true, continue as normal

If the regexp is true, count it by appending a character (x) to the hold space for each occurrence.

Condtional on the count (in the first solution, 1 and the second solution, 2) carry out an action.

In the first solution:

  • append a line containing E

In the second solution:

  • print the current line
  • append the next two lines
  • delete the current pattern space

If the conditional is not true, continue as normal.

N.B. the first solution can be shortened using ranges:

sed '0,/B/!b;//aE' file

or for variations of sed that do not allow GNU extentions (0,address)

sed -e '/B/{aE' -e ':a;n;ba}' file

Problem inserting on first match only using GNU sed

The link you show in the comment is not quite the same command sequence that you're trying to use. If you want to use the same technique, try:

sed -i '0,/^\(author:.*\)/s//\1\nNew Inserted Line/' myfile.txt

Sed insert before first match

two things you may consider :

1) use s/.../.../ instead of i

2) special chars in your thestring which would conflict with sed's s separator. In your example the slash in/p>

this should work for your needs:

 sed  -i "0,/<p/ s_^_$thestring\n&_" file

Command to insert lines before first match

For lines consisting of "testing" exactly:

sed '0,/^testing$/s/^testing$/tested\n&/' file

For lines containing "testing":

sed '0,/.*testing.*/s/.*testing.*/tested\n&/' file

For Lines Starting with "testing"

sed '0,/^testing.*/s/^testing.*/tested\n&/' file

For lines ending with "testing":

sed '0,/.*testing$/s/.*testing$/tested\n&/' file

To update the content of the file with the result add "-i", example:

sed -i '0,/testing/s/testing/tested\n&/' file

Insert line after match using sed

Try doing this using GNU sed:

sed '/CLIENTSCRIPT="foo"/a CLIENTSCRIPT2="hello"' file

if you want to substitute in-place, use

sed -i '/CLIENTSCRIPT="foo"/a CLIENTSCRIPT2="hello"' file

Output

CLIENTSCRIPT="foo"
CLIENTSCRIPT2="hello"
CLIENTFILE="bar"

Doc

  • see sed doc and search \a (append)

Add file content in another file after first match only

You're getting that error because if you have an address range (ADDR1,ADDR2) you can't put another address after it: sed expects a command there and / is not a command.

You'll want to use some braces here:

$ seq 20 > file
$ echo "new content" > tmpFile
$ sed '0,/5/{/5/ r tmpFile
}' file

outputs the new text only after the first line with '5'

1
2
3
4
5
new content
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

I found I needed to put a newline after the filename. I was getting this error otherwise

sed: -e expression #1, char 0: unmatched `{'

It appears that sed takes the whole rest of the line as the filename.

Probably more tidy to write

sed '0,/5/ {
/5/ r tmpFile
}' file

Full transparency: I don't use sed except for very simple tasks. In reality I would use awk for this job

awk '
{print}
!seen && $0 ~ patt {
while (getline line < f) print line
close(f)
seen = 1
}
' patt="5" f=tmpFile file

sed append line on 1 occurrence only

Actually, it's not sed, but maybe awk can help you.

$> cat ./file
ServerName *
ServerAlias *
ServerAlias *

<Directory>

$> awk '{print} /^ServerAlias/ && !n {print "S2"; n++}' ./file
ServerName *
ServerAlias *
S2
ServerAlias *

<Directory>

UPD: mistake is fixed now, thanks glenn_jackman



Related Topics



Leave a reply



Submit