grep a file and pipe the output to sed and store sed output in a file
Solution 1
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 regexgold
.s/green/red/
performs the substitutionp
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
Solution 2
grep -l "gold" source.txt
will output source.txt
if the file contains the word gold
xargs sed 's/green/red/'
will run sed 's/green/red/' source.txt
and the final redirect saves the result in your output.
If I understand your intent correctly, you want the following command:
sed -n '/gold/s/green/red/p' source.txt > pol.txt
The /gold/
selects lines matching gold
and the s
command does the replacement you want.
Related videos on Youtube
Driven
Updated on September 18, 2022Comments
-
Driven over 1 year
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
, pipegrep
output tosed
replace a string and store that line in a new filepol.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.txtsed: 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.-
Giacomo1968 almost 8 yearsWhat OS are you on? And what was the
source.txt
file saved with? To me this seems like it might be a mixup between carriage returns and line-feeds getting mixed up. -
G-Man Says 'Reinstate Monica' almost 8 yearsAs John1234’s answer shows, you hardly ever need to use
grep
andsed
together —sed
by itself can probably do anything that the two programs can do together. If you have a problem where you have multiple input files and you need to process only the ones that contain “gold”, you should probably explain that; otherwise, people who are trying to answer your question have one hand tied behind their back. (Please do not respond in comments; edit your question to make it clearer and more complete.) As Satya Mishra explains,grep -l "gold" source.txt
will outputsource.txt
… (Cont’d) -
G-Man Says 'Reinstate Monica' almost 8 years(Cont’d) … if the file contains the word “gold” (and nothing if it doesn’t). If the only thing that you’re writing into your pipe is the
source.txt
filename, there’s no way the process on the right side of the pipe can know that you want it to process only the lines that contain “gold” unless you build that into the command (as John demonstrates). (His command can be simplified a little, tosed -n '/gold/s/green/red/p' source.txt
. And, if you can writesed 's/green/red/'
, is this really so “frightening” that “it will be a pain” to maintain?)
-
-
Driven almost 8 yearsthanks john for your input but, grep is needed. Grep will be use as tester before handing output to sed.
-
John1024 almost 8 years@Driven Why do you think that grep is needed as a tester? sed is perfectly capable of doing the same test. Unless you have some other requirement not yet explained?
-
Driven almost 8 yearsI'm planning to automate the process with a for loop through several files.
-
John1024 almost 8 yearsTo process several files, there is no need for a
for
loop. Sed can take multiple file names on one command line. (If there are still more requirements, instead of revealing your goal piecemeal, you might as well just specify them all at once.) -
John1024 almost 8 years@Driven I have added a version with a grep pipeline.
-
Driven almost 8 yearsthanks, John the main reason is that I'm not really good with sed, in fact I always try to stay away from it. sed syntax is too frightening and I know that in a long run it will be a pain if I need to improve the script
-
John1024 almost 8 years@Driven In honor of that, I added an
awk
solution. As withsed
, many filenames can be placed on theawk
command line.