iglpdc
11/28/2013 - 3:12 AM

Substitutes a word by another word in all the files under a given directory.

Substitutes a word by another word in all the files under a given directory.

#!/bin/bash
#
# Substitutes the word 'word_to_change' for the word 'new_word' in all the
# files inside a directory.
# 
# Both words can contain white-spaces, but if the word to be changed is
# splitted into two different lines the change is not made. The directory is
# searched recursively.
# 
#################################################################### 
function man() 
{ 
    echo -e "Substitutes the word 'word_to_change' for the word 'new_word' in"\ 
    "all the files inside a directory.\n" 
}

function usage()
{
    echo -e "Usage: `basename $1` [-d dir] word_to_change new_word"
    echo -e "Options:"
    echo -e "\t -n do a dry run" 
    echo -e "\t -h this help" 
    echo -e "\t -d find files recursively from this dir"
}

function get_files_to_change()
{
    echo $(grep -R  $1 $2 | cut -d: -f1 | uniq)
}

function run()
{
    local FILES_TO_CHANGE=$(get_files_to_change $1 $3)
    if [ $DRY_RUN -eq 1 ]
    then
        echo -e "This is a dry-run; no changes will be made."
        echo -e "Looking for files in $DIR."
        echo -e "Changing $1 to $2"
	echo -e "Files to change:"
        for i in ${FILES_TO_CHANGE[*]}; do echo $i; done;
    else
        for i in ${FILES_TO_CHANGE[*]}; do sed -i.bak s/$1/$2/g $i; done;
        EXIT_STATUS=$?
        if [ $EXIT_STATUS -eq 0 ]
        then 
            for i in ${FILES_TO_CHANGE[*]}; do rm $i.bak; done;
        else 
            exit $EXIT_STATUS
        fi
    fi
}
####################################################################
DRY_RUN=0
DIR=$PWD 

while getopts ":nhd:" opt; do
    case $opt in
        n) DRY_RUN=1;;
        d) DIR=$OPTARG;; 
        h) man; usage $0 ; exit 0;;
        [?]) man; usage $0; exit 1;;
    esac
done
shift $((OPTIND-1))

NUM_ARGS=$#
if [ $NUM_ARGS -ne 2 ]
then
    echo -e "Wrong number of arguments.\n"
    usage $0
    exit 1
else
    ARGS=("$@")
    run "${ARGS[0]}" "${ARGS[1]}" $DIR
fi