8

I am learning sed, so in this context I am trying to replace 2nd occurrence of word 'line'. Therefore, I issued following command:

(zet:pc:~/text) sed 's/line/LINUX/2' mytextfile
this is line 1
this is line 2
this is line 3
this is line 4
this is line 5

But from the output, you can see that 'sed' is not replacing 2nd occurrence of the world 'line'. So, am I making any mistake here?

Jeff Schaller
  • 67,283
  • 35
  • 116
  • 255

3 Answers3

16

s/../../2 replaces the second occurrence on each line.

You can make it work if you read the file as one line:

With GNU sed:

sed -z 's/line/LINUX/2' mytextfile

With normal sed:

tr '\n' '\0' < mytextfile  |  sed 's/line/LINUX/2'  |  tr '\0' '\n'

Note that this will produce incorrect results in the highly unlikely case that the file already contains nul bytes.


To replace the first occurrence on the 2nd line, see other answers :-)

pLumo
  • 22,565
5

In your file, the second occurrence is on the second line so what you need is this:

sed '2s/line/LINUX/' mytextfile

To edit the file in-place:

sed -i '2s/line/LINUX/' mytextfile

The 2s is to make the change on the second line. Your command would only work if the string line appeared more than once on one or more lines.

Nasir Riley
  • 11,422
  • 2
    OP asks for replace 2nd occurrence, not first occurrence on 2nd line. – pLumo May 20 '20 at 15:55
  • @pLumo why not? This is exactly what the OP is asking for, isn't it? This will replace the word line on the second line. It produces the same output as your -z approach but is more portable and doesn't require reading the entire file as a single line. – terdon May 20 '20 at 15:59
  • 1
    It does the same for that piece of text, but it is till not what OP is asking for. Especially considering "I am learning sed". – pLumo May 20 '20 at 16:00
  • @pLumo I guess it depends on how you read the question. I read it as the OP misunderstanding what the /2 does, since they clearly expected it to make the change on the second line. Good to have both approaches, anyway. – terdon May 20 '20 at 16:01
  • Fair enough ;-) I added a note to my answer. – pLumo May 20 '20 at 16:08
  • @pLumo I understand, but according to the contents of the file, the second occurrence of the string line is, in fact, on the second line. As terdon stated, he clearly wanted the change to occur on the second line and my answer provides that. It does the exact same thing as your answer and I even provided the case where the command that he was using would work. – Nasir Riley May 20 '20 at 16:12
  • 1
    I disagree with "he clearly wanted the change to occur on the second line", but as @terdon has said: "Good to have both approaches" ;-) – pLumo May 20 '20 at 16:18
  • @pLumo Where else in the file would he have possibly wanted it to occur? That string only appears once on each line. Had it appeared more than once on each line then his command would have worked and there wouldn't have been any need for him to ask the question. – Nasir Riley May 20 '20 at 16:39
  • OP says he's learning, so I guess the text is just an example. – pLumo May 20 '20 at 16:52
  • Worked perfectly for my particular scenario my required line number. Thanks – Promise Preston Sep 11 '22 at 12:18
3

For Line parsing , you should mention the line number preceding the command 's'

$ echo "this is line 1
this is line 2
this is line 3
this is line 4
this is line 5" | sed -e '2s/line/LINUX/'
this is line 1
this is LINUX 2
this is line 3
this is line 4
this is line 5

So, for you the command is :

sed -e '2s/line/LINUX/' mytextfile

And yes , if regardless of line number , if you want to just replace the 2nd occurrence in the whole file , pLumo's answer is right.

sed -z 's/line/LINUX/2' mytextfile