Home > front end >  Replacing multiple lines using sed
Replacing multiple lines using sed

Time:12-17

Good day!

I'm trying to figure out how hold space and pattern space work in sed so I can use it to replace multiple strings.

For example, if you want to replace the first and second lines with NEW STRING:

echo -e "aa\nbb\ncc\ndd\n"
aa
bb
cc
dd

In order to get such a STDOUT:

NEW STRING
NEW STRING
cc
dd

I'm trying to do something like:

echo -e "aa\nbb\ncc\ndd\n" | sed -e 'commands'

I know it can be done this way:

echo -e "aa\nbb\ncc\ndd\n" | tr '\n' '\0' | sed -e 's#aa#NEW STRING#;s#bb#NEW STRING#' | tr '\0' '\n'
NEW STRING
NEW STRING
cc
dd

But how do you solve this problem without using tr?

Can you also suggest a case where we don't know the line numbers? We only know that aa comes after bb.

CodePudding user response:

sed commands accept a range of lines to operate on:

$ printf "%s\n" aa bb cc dd | sed '1,2s/.*/NEW STRING/'
NEW STRING
NEW STRING
cc
dd

Some like s work on individual lines in the range, some treat the whole range as a block to apply the command to:

$ printf "%s\n" aa bb cc dd | sed '1,2c\
NEW STRING'
NEW STRING
cc
dd

For example, one line is aaa, another line is bbb. We know that aaa comes before bbb, but we don't know their numbers in the file.

One approach I threw together (There might be better; and only tested with GNU sed)

$ printf "%s\n" qq rr aa bb cc aa xx dd |
  sed '/^aa$/{N; /^aa\nbb$/{s/.*/NEW STRING\nNEW STRING/; p; d}; P; D}'
qq
rr
NEW STRING
NEW STRING
cc
aa
xx
dd

If the current line is aa, N to appends the next line to the current pattern space. If it's now aa\nbb, replace it with two NEW STRING lines, print out the pattern space, delete it and start over with a new line. If the pattern space has something else, print out everything up to the first newline, delete that text from the pattern space, and start again with just that second line that was read by N in it.

CodePudding user response:

If the goal is to experiment with pattern space and hold space, then this would be an example:

echo -e "aa\nbb\ncc\ndd" | sed '1{ s/.*/NEW STRING/; h}; 2g'

Output:

NEW STRING
NEW STRING
cc
dd

Replace first line with NEW STRING and then copy pattern space to hold space (h). In second line copy hold space to pattern space (g).

  • Related