Search and replace using grep (not sed)

grepsed

I’ve been reading about sed and found that it was evolved from grep command.

According to https://en.wikipedia.org/wiki/Sed ,

First appearing in Version 7 Unix, sed is one of the early Unix
commands built for command line processing of data files. It evolved
as the natural successor to the popular grep command. The original
motivation was an analogue of grep (g/re/p) for substitution, hence
"g/re/s".

Sed search and replace

sed 's/old/new/' Example.txt

Thus, I was wondering if grep can perform the search and replace function just like sed.

If this is possible, please let me know how to accomplish the same via grep, and not via sed.

Best Answer

grep is only meant to (and was only initially) print(ing) the lines matching a pattern. That's what grep means (based on the g/re/p ed command).

Now, some grep implementations have added a few features that encroaches a bit on the role of other commands. For instance, some have some -r/--include/--exclude to perform part of find's job.

GNU grep added a -o option that makes it perform parts of sed's job as it makes it edit the lines being matched.

pcregrep extended it with -o1, -o2... to print what was matched by capture groups. So with that implementation, even though it was not designed for that, you can actually replace:

sed 's/old/new/'

with:

pcregrep --om-separator=new  -o1 -o2 '(.*?)old(.*)'

That doesn't work properly however if the capture groups match the empty string. On an input like:

XoldY
Xold
oldY

it gives:

XnewY
X
Y

You could work around that using even nastier tricks like:

PCREGREP_COLOR= pcregrep --color=always '.*old.*' |
  pcregrep --om-separator=new -o1 -o2 '^..(.+?)old(.+)..' |
  pcregrep -o1 '.(.*).'

That is, prepend and append \e[m (coloring escape sequence) to all matching lines to be sure there is at least one character on either side of old, and strip them afterwards.

Related Question