Home > Mobile >  Understand N command with sed
Understand N command with sed

Time:07-08

I am trying to edit a file with some IPs.

There is an empty line at the end of the file. I have multiples workers (XXXX, YYYY, ZZZZ and others). They all have two network interface in my file (ens192 & ens224). Each cni have one IP (ip192 for the cni ens192, and ip224 [worker number] for ens224)

My goal is to add ens256 after each ip224 with one sed command, but I'm struggling to understand how sed works. Can someone explain why is sed is doing this:

> cat file
workerXXXX
ens192
ip192
ens224
ip2241

workerYYYY
ens192
ip192
ens224
ip2242

workerZZZZ
ens192
ip192
ens224
ip2243

> sed -n '{N; /^ens224\s/{p}}' file
>

No output!

But if I edit the file:

> cat file
workerXXXX
ens192
ip192
ens224
ip2241
randomelinehere

workerYYYY
ens192
ip192
ens224
ip2242

workerZZZZ
ens192
ip192
ens224
ip2243

> sed -n '{N; /^ens224\s/{p}}' file
ens224
ip2242
ens224
ip2243

Why is sed printing lines here and not before? Why is it only printing line after it reaches 'randomlinehere' ?

I have found that if I add a 'D' at the end, everything work as expected (without the randomlinehere) sed -n '{N; /^ens224\s/{p}; D}' file And I think I'm close to what I need. (I just need to add 'ens256' after I find my pattern, but for now the 'a' is consuming the closing bracket with sed -n '{N; /^ens224\s/{a ens256}; D}' file)


EDIT:

My goal was to do this:

workerXXXX
ens192
XXX.XXX.XXX.XXX
ens224
XXX.XXX.XXX.XXX

workerXXXX
ens192
XXX.XXX.XXX.XXX
ens224
XXX.XXX.XXX.XXX
ens256

With sed because I wanted to learn more about this command. I encountered a weird behavior with the \N command, that's why I asked this question.

The 'ip224' is random, so I cannot use sed '/ip224/a ens256' The goal is to add text (ens256) two line after a pattern (ens224)

CodePudding user response:

Using sed -n '{N; /^ens224\s/{p}}' file does not print anything, because \N pulls the next line into the pattern space, so you test the pattern against 2 lines with a newline in between.

For the first example data, the line in the pattern space looks for example like ip192\nens224

The string ens224 is not at the start of the line, to the ^ does not match, and the \s at the end can not match a whitespace char.

If you add randomelinehere, then pulling the next line in the pattern space will now have ens224 at the beginning of the line for the last 2 occurrences .

The line after the addition of the extra line now looks like ens224\nip2242 and that is why you see 2 times 2 lines printed in your question.


What you might do is match the line starting with ens224 and then append the text:

sed '/^ip224/a ens256' file

Or if you want to append a line to the match only:

sed -n '/^ip224.*/{s//&\nens256/p}' file

CodePudding user response:

If the goal is to add a string 2 lines after a match, then you can try this sed

$ sed '/ens224/{N;s/.*$/&\nens256/}' input_file
workerXXXX
ens192
XXX.XXX.XXX.XXX
ens224
XXX.XXX.XXX.XXX
ens256
  • Related