Issue
I created a very complicated sed command to remove parts that match certain patterns:
sed 's/...//Ig; s/...//Ig; s/...//Ig'
But I found that I made a mistake, I should only edit the part after the first occurrence of :
. How to modify this sed command and/or using other commands to achieve it?
The lines to edit are actually output of grep, e.g.:
/foo/bar:foobar
/foobar/foo/bar:foo_bar
Solution
I'm assuming for simplicity that you want to substitute each foo
occurring after the first :
with FOO
.
sed 'h # save the current line in the hold space
s/[^:]*:// # delete everything up to the marker
s/foo/FOO/g # YOUR COMPLICATED COMMAND GOES HERE
x # swap pattern and hold space
s/:.*/:/ # delete from the first : to the end in the original line
G # append hold space (: with whatever follows it)
s/\n//' yourfile # remove the newline that comes with G
The above code was updated upon the suggestion received in a comment.
The original answer is below. Even if in this case it's a bit of an overkill, it shows that you can use the null character in sed
, \x0
, as a "marker" that you can generally assume is not in a text file (in contrast to using e.g. _xxx_
which could potentially be in a file already). (This second version substitutes for occurrences of foo
before :
, in line with when I misread the question.)
sed 'h # save the current line in the hold space
s/:/\x0:/ # mark the first : by prepending a null character
s/.*\x0// # delete everything up to the marker
x # swap pattern and hold space
s/:.*// # delete from the first : to the end in the original line
s/foo/FOO/g # YOUR COMPLICATED COMMAND GOES HERE
G # append hold space (: with whatever follows it)
s/\n//' yourfile # remove the newline that comes with G
Answered By - Enlico Answer Checked By - Senaida (WPSolving Volunteer)