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.
2 Answers
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
-ntells sed not to print lines unless we explicitly ask it to./gold/selects lines that match the regexgold.s/green/red/performs the substitutionpprints.
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 7grep -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.