What the script requires is that you provide a file containing pairs of "from and to" values delimited by a tilde (~)
eg
street~str
mr~mister
addr~address
Then you just call the script, give it a path to the file (above) and a file extension to search for (eg. txt) and it does the job quite nicely.
Here is the script:
#!/bin/bash
# @author Louis van der Merwe mailto:TheMandibleClaw@gmail.com
echo
echo "*********************************************************"
echo "* BULK SEARCH AND REPLACE *"
echo "*********************************************************"
echo
if [ $# -eq 0 ]
then
echo "usage $0 {path to matches file (file must contain pairs of "old value~new value")} file extension]"
echo
exit -1
fi
FILE_PATH="$1"
EXTENSION="*"
SEARCH_PATH="."
test $# -eq 2 && EXTENSION="$2"
declare -a MATCHES
i=-1
while read line;
do
if [ -n "$line" ]
then
i=$(($i + 1))
MATCHES[$i]="$line"
fi
done < ${FILE_PATH}
find ${SEARCH_PATH} -iname "*.$EXTENSION" | while read f;
do
F_TOTAL=0
echo -ne "\n$f "
if [ -w "$f" ]
then
for m in $(seq 0 ${i});
do
FROM=$(echo ${MATCHES[$m]} | cut -d~ -f1)
TO=$(echo ${MATCHES[$m]} | cut -d~ -f2)
M_TOTAL=$(grep "$FROM" "$f" | grep -v grep | wc -l)
echo -ne " [$FROM] " && \
if [ $M_TOTAL -gt 0 ]
then
F_TOTAL=$(( $F_TOTAL + $M_TOTAL))
cat "$f" | sed -e "s/${FROM}/${TO}/g" > "${f}.new" && mv -f "${f}.new" "${f}"
for s in $(seq $M_TOTAL);
do
echo -ne "."
done
fi
done
else
echo -ne " is read-only - skipping"
fi
echo -ne " ($F_TOTAL replacements) "
done
echo -ne "\n\n"
exit 0
Whilst there are obviously better languages such as python that one can use to solve such a problem, I always enjoy writing bash scripts. They always remind my of why I love gnu, simple applications which each perform a specific job well; which can be strung together to solve complex problems.
No comments:
Post a Comment