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
).