Replacing substrings in file names and contents in Unix/Linux shell script
Today I’d like to share two useful code snippets to deal with string replacement in file names and contents. Each of those two operations can be done in a single pipe, without intermediate files and variables and thus fast and without side effects.
Suppose you want to replace some $STRING_ONE with $STRING_TWO in files and folders’ names (rename them) and in all files’ contents for some given directory $BASEDIR.
cd $BASEDIR
To rename all files and folders by replacing $STRING_ONE to $STRING_TWO:
find . -name "*$STRING_ONE*" -print \ | sed "h; s/$STRING_ONE\([^/]*\)$/$STRING_TWO\1/; H; g" \ | sed -n 'N; 1! G; $ p; h' | xargs -L 2 mv
To replace string $STRING_ONE with $STRING_TWO in all files:
grep -lr "$STRING_ONE" . \ | xargs sed -i '' -e "s/$STRING_ONE/$STRING_TWO/g"
The second operation uses grep to select files that contain string to be replaced before actual replacement. This makes renaming more effective when there are a lot of files in the directory and only some of them contain $STRING_ONE, but there are a lot of such substrings to be replaced.
Code snippets were tested on Mac OS X 10.6.5.
