0

I'm using centos 7. sed command to replace second occurrence not working to me. I tried the following solutions:

The file:

this
foo
is
a test
file
this
foo

I am trying to run:

sed 's/foo/bar/2g' file
sed 's/foo/bar/2' file
sed -i 's/foo/bar/2g' file

I wish to replace all occurrences of "foo" with "bar" from the second one.

Nike
  • 1,223
  • 2
  • 19
  • 42
Utz
  • 13
  • 6
  • The answer you tried to emulate is aimed at replacing the second occurrence of the pattern *in each line*. It contains no mechanism or logic for tracking occurrences of the pattern across multiple lines. – John Bollinger Nov 18 '21 at 14:15
  • Do you want to replace *only* the second appearance in the whole file? Or else, maybe every even-numbered appearance? Or the second and all subsequent appearances? Can you assume that there will be at least two appearances? Can you assume that there will be exactly two? – John Bollinger Nov 18 '21 at 14:18

2 Answers2

1

This will perform a substitution on the second and all subsequent lines containing the specified pattern (/foo/):

sed ':1; /foo/! { n; b1 }; :2; n; s/foo/bar/; b2' file

It has two parts:

  • :1; /foo/! { n; b1 }; is a loop, reading lines and outputting them unchanged until the first is encountered that matches /foo/.
  • :2; n; s/foo/bar/; b2 is a loop that repeatedly outputs the current line, reads the next and performs the substitution s/foo/bar/. The substitution is a harmless no-op for lines that do not contain the pattern.

The first match to the pattern is the current line at the beginning of the second loop, so it is output unchanged when second loop first executes its n command.

John Bollinger
  • 160,171
  • 8
  • 81
  • 157
0

This might work for you (GNU sed):

sed -z 's/foo/bar/2' file

Slurps the whole for file into the pattern space and replaces the second occurrence of foo with bar.

Alternative:

sed 'H;$!d;x;s/.//;s/foo/bar/2' file 
potong
  • 55,640
  • 6
  • 51
  • 83