How to Search and Replace Using Grep

Using grep and sed to find and replace a string

You can use find and -exec directly into sed rather than first locating oldstr with grep. It's maybe a bit less efficient, but that might not be important. This way, the sed replacement is executed over all files listed by find, but if oldstr isn't there it obviously won't operate on it.

find /path -type f -exec sed -i 's/oldstr/newstr/g' {} \;

How can I grep/sed taking find/replace pairs from a file?

You can make a file with a list of sed commands like this in a file called commands.sed:

s|cat|cats|g
s|dog|dogs|g
s|person|people|g

and run it on some input with:

echo "House mouse cat dog person dog person" | sed -f commands.sed

and it will replace cat with cats, dog with dogs and person with people producing:

House mouse cats dogs people dogs people

So we want to turn your file with substitutions into a command file like that - using sed! So, if your replacements file subs.txt contains lines like this with the two words on each line separated by a TAB:

cat cats
dog dogs
person people

That would be:

sed -e 's/^/s|/' -e $'s/\t/|/' -e 's/$/|g/' subs.txt > commands.sed

and then you can apply it with:

sed -f commands.sed SomeFile

Rather than creating a file with the commands in, we can run a process substitution like this to dynamically generate them, and do it all in one go with:

echo "House mouse cat dog person dog person" | sed -f <(sed -e 's/^/s|/' -e $'s/\t/|/' -e 's/$/|g/' subs.txt)

Find and Replace string in all files recursive using grep and sed

As @Didier said, you can change your delimiter to something other than /:

grep -rl $oldstring /path/to/folder | xargs sed -i s@$oldstring@$newstring@g

Replace string using grep and sed

sed will take multiple files as arguments, so this should work:

sed -i '/AB_/s//YZ_/g' *

(Note that -i is non-standard)

grep regex, replace specific find in text file

grep doesn't do replacements. You can try sed, e.g.:

sed 's/Copyright (C) \([0-9]\{4\}\)-[0-9]\{4\} by/Copyright (C) \1-2013 by/'

or as Kent notes:

sed 's/\(Copyright (C) [0-9]\{4\}\)-[0-9]\{4\} by/\1-2013 by/'

or ssed:

ssed -R 's/(?<=Copyright \(C\) )([0-9]{4})-[0-9]{4}(?= by)/\1-2013/'

Using grep and sed to replace one string with another

Provided you have a sed which supports the -i option,

sed -i 's/version: .*/version: 1.2.3/' file1 file2 file3 ...

You may want to tweak the regex wildcard; .* matches through the end of the line, whereas [.0-9]* matches the longest possible sequence of dots and digits. You might also want to permit for variations in surrounding whitespace ... But since this is probably among the top 10% FAQs on this site, go look for similar questions at this point.

To obtain the replacement string from file1 and apply it to file2, file3, etc, something like

new=$(sed -n 's/version: //p' file1)
# Use double quotes, not single, in order to expand $new
sed -i "s/version: [.0-9]*/version: $new/" file2 file3 ...

The first sed invocation will only print lines on which "version: " was found and removed (replaced with an empty string). Presumably there will only be one such line in the file. Pipe the output to head -n 1 or uniq or something, or find / create a more elaborate sed script.

You normally use single quotes around literal strings, but since you don't want a literal $new in the replacement, we use double quotes, which allow the shell to perform variable replacement (and a number of other substitutions we don't go into here) in the quoted string.

Using sed and grep/egrep to search and replace

Use this command:

egrep -lRZ "\.jpg|\.png|\.gif" . \
| xargs -0 -l sed -i -e 's/\.jpg\|\.gif\|\.png/.bmp/g'
  • egrep: find matching lines using extended regular expressions

    • -l: only list matching filenames

    • -R: search recursively through all given directories

    • -Z: use \0 as record separator

    • "\.jpg|\.png|\.gif": match one of the strings ".jpg", ".gif" or ".png"

    • .: start the search in the current directory

  • xargs: execute a command with the stdin as argument

    • -0: use \0 as record separator. This is important to match the -Z of egrep and to avoid being fooled by spaces and newlines in input filenames.

    • -l: use one line per command as parameter

  • sed: the stream editor

    • -i: replace the input file with the output without making a backup

    • -e: use the following argument as expression

    • 's/\.jpg\|\.gif\|\.png/.bmp/g': replace all occurrences of the strings ".jpg", ".gif" or ".png" with ".bmp"



Related Topics



Leave a reply



Submit