Linux – grep a file and pipe the output to sed and store sed output in a file

bashgreplinuxsedshell-script

Contents of source.txt:

gold  green white black blue
yellow magenta brown 
tram kilo charlie tango

Hi everyone! I need to solve a mystery.

I'm trying to run a small script to grep a file source.txt, pipe grep output to sed replace a string and store that line in a new file pol.txt

grep -l "gold" source.txt | xargs sed  's/green/red/' >  pol.txt

Instead of having the only that line stored in pol.txt:

gold  red white black blue

I have the entire file itself with the string I replaced

gold  red white black blue
yellow magenta brown 
tram kilo charlie tango

When I remove the option -l from grep command I have this and of course nothing in pol.txt

sed: can't read gold: No such file or directory
sed: can't read green: No such file or directory
sed: can't read white: No such file or directory
sed: can't read black: No such file or directory
sed: can't read blue: No such file or directory

grep is needed as a tester and unfortunately " if " is not an option.

Best Answer

To select any line containing gold from source.txt and replace the first occurrence of green with red:

$ sed  -n '/gold/{s/green/red/; p}' source.txt 
gold  red white black blue

To save that in a file:

sed  -n '/gold/{s/green/red/; p}' source.txt  >pol.txt

How it works

  • -n tells sed not to print lines unless we explicitly ask it to.

  • /gold/ selects lines that match the regex gold.

  • s/green/red/ performs the substitution

  • p prints.

Using awk

With the same logic:

$ awk '/gold/{gsub(/green/, "red"); print}' source.txt 
gold  red white black blue

Using grep

If we are forced, for reasons not yet explained, to use a grep pipeline, then try:

$ grep -l --null "gold" source.txt | xargs -0 sed  -n '/gold/s/green/red/p'
gold  red white black blue
Related Question