Saturday, November 22, 2008

slackware - find and replace

I occasionally encounter compatibility problems with Internet Explorer and Firefox when writing site pages. When I do, finding and replacing one word across many files can be a problem. For example, I recently learned that Internet Explorer does not process the word "grey" - it apparently has to be spelled "gray". So how to find and replace all instances of "grey" with "gray" across all the directories on the site?

grep
Of course, finding text is no problem for grep. If it's only one or two files, I can have grep locate the file for me and change them by hand.
grep -lr 'text' *
where "l" provides the line number, "r" will recursively check all files, 'text' is the text I want to locate, and "*" means all files will be checked.

sed
To replace the text, we can use sed

grep and sed script
To both find and replace the text, we need a mix of sed and grep together. A simple bash script follows that does it just fine.
#!/bin/bash

function search {
find $1 -type f \( -name '*php' \) -print | while read file
do
echo replacing \"$2\" with \"$3\" in $file
sed "s,$2,$3,g" < "$file" > "$file".tmp
mv "$file".tmp "$file"
done
}

function nothing {
echo "dir: $1 search string: $2 replace string: $3"
}

# A directory has been given. Search for files containing the term, and replace it
if [ -d "$1" ]; then
search $1 $2 $3

# A file has been given. Search the file for the term and replace it
elif [ -f "$1" ]; then
sed "s,$2,$3,g;" < "$1" > "$1".tmp
mv "$1".tmp "$1"

# A file to parse or test has been given. If parse, set the directory,
# then step though every file in the directory replacing search / rplace pairs.
# Keep going until there are no more pairs.
elif [ "$1" == '-f' ] || [ "$1" == '-t' ] && [ -f "$2" ]; then
index=0
cat $2 | while read line
do
if [ $index -eq 0 ] && [ -d "$line" ]; then
dir=$line
elif [ $index -eq 0 ] && [ ! -d "$line" ]; then
exit
elif [ $index -gt 0 ]; then
findSt=`echo ${line%% *}`
repSt=`echo ${line##* }`
fi
if [ "$1" == '-f' ] && [ ! "$repSt" == '' ] && [ ! "$findSt" == '' ]; then
search $dir $findSt $repSt
elif [ "$1" == '-t' ] && [ ! "$repSt" == '' ] && [ ! "$findSt" == '' ]; then
nothing $dir $findSt $repSt
fi
let "index += 1"
done
else
echo "Search and replacer:"
echo "useage:"
echo "$0 [directory to search] [phrase to search for] [replacement phrase]"
echo "$0 [file to search] [phrase to search for] [replacement phrase]"
echo "$0 [-f|-t] [file to parse]"
echo "To parse a file the first line should be the directory, then each line after is a pair of terms"
echo "and replacements seperated by white space. If the -f os given, the file will be parsed. If -t "
echo "is given then the file will be read and the terms that would be replaced are output."
echo
fi

You can see at the top that this only works on php files, so I just changed the "php" to "css".

No comments: