I had a need to perform a search and replace operation on all files in a directory of files. Effectively I needed a recursive sed. I couldn't find one and wrote this script. This is version .1, but worked for my needs, hopefully others find it useful. It is probably a smart practice to backup your set of files before running any batch operation on them. The script is released under the GPL2 License.
#!/bin/bash # ------------------------------------------------------------------ # # Shell program to run a search and replace operation on files recursively. # # Copyright 2008, Steve Francia <steve.francia+search_and_replace@gmail.com>. # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License as # published by the Free Software Foundation; either version 2 of the # License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # Description: # # # Usage: # # search_and_replace.sh [ -h | --help ] [OPTIONS] [ARGUMENT1] [ARGUMENT2] # # Options: # # -h, --help Display this help message and exit. # --version Display program version. # # Arguments: # # ARGUMENT1 The token to search for. # ARGUMENT2 The token to replace it with. # # External programs: # # getopt - parse command options (enhanced) # mktemp - make temporary filename (unique) # sed - stream editor # basename - strip directory and suffix from filenames # # Revision History: # # 2008-07-25 Initial Script Created # See ChangeLog for additional changes # # # ------------------------------------------------------------------ ##### Preamble ##### # ------------------------------------------------------------------ # Constants # ------------------------------------------------------------------ declare -r PROGNAME=$(basename $0) declare -r VERSION="0.1" declare -r DESCRIPTION="a Shell program to run a search and replace operation on files recursively." ##### Functions ##### # ------------------------------------------------------------------ # Functions # ------------------------------------------------------------------ function clean_up() { # ------------------------------------------------------------------ # Function to remove temporary files and other housekeeping # No arguments # ------------------------------------------------------------------ #rm -f ${TEMP_FILE1} return } # end of clean_up function error_exit() { # ------------------------------------------------------------------ # Function for exit due to fatal program error # Arguments: # 1 (optional) string containing descriptive error message # ------------------------------------------------------------------ echo "${PROGNAME}: ${1:-"Unknown Error"}" >&2 clean_up exit 1 } # end of error_exit function graceful_exit() { # ------------------------------------------------------------------ # Function called for a graceful exit # No arguments # ------------------------------------------------------------------ clean_up exit } # end of graceful_exit function signal_exit() { # ------------------------------------------------------------------ # Function to handle termination signals # Arguments: # 1 (optional) signal_spec # ------------------------------------------------------------------ case $1 in INT) echo "$PROGNAME: Program aborted by user" >&2 clean_up exit ;; TERM) echo "$PROGNAME: Program terminated" >&2 clean_up exit ;; *) error_exit "$PROGNAME: Terminating on unknown signal" ;; esac } # end of signal_exit function make_temp_files() { # ------------------------------------------------------------------ # Function to create temporary files # No arguments # ------------------------------------------------------------------ # Use user's local tmp directory if it exists if [ -d ~/tmp ]; then TEMP_DIR=~/tmp else TEMP_DIR=/tmp fi # Temp file for this script, using paranoid method of creation to # insure that file name is not predictable. This is for security # to avoid "tmp race" attacks. If more files are needed, create # using the same form. TEMP_FILE1=$(mktemp -q "${TEMP_DIR}/${PROGNAME}.$$.XXXXXX") if [ "$TEMP_FILE1" = "" ]; then error_exit "cannot create temp file!" fi } # end of make_temp_files function usage() { # ------------------------------------------------------------------ # Function to display usage message (does not exit) # No arguments # ------------------------------------------------------------------ echo "Usage: ${PROGNAME} [-h | --help] [OPTIONS] [SEARCH] [REPLACE]" } # end of usage function helptext() { # ------------------------------------------------------------------ # Function to display help message for program # No arguments # ------------------------------------------------------------------ cat <<EOF ${PROGNAME} ${VERSION} This is a program to ${DESCRIPTION}. $(usage) Options: -h, --help Display this help message and exit. -t, --test Display what is actualy being passed to sed. -e [ext], --extension [ext] Only replace text found in files found with extension --version Display program version. Arguments: SEARCH The token to search for. REPLACE The token to replace it with. Hints: Please escape your strings. If you are unsure, please test with -t first. EOF } # end of helptext function search_and_replace() { # ------------------------------------------------------------------ # Function to [INSERT FUNCTION DESCRIPTION] # Arguments: # 1 (required) arg1 # 2 (required) arg2 # ------------------------------------------------------------------ if [ $testmode -ne 0 ] ; then echo "passing 's/$1/$2/g' into sed" graceful_exit; fi # Fatal error if required arguments are missing if [ "$1" = "" ]; then error_exit "search_and_replace: missing argument 1" fi if [ "$2" = "" ]; then error_exit "search_and_replace: missing argument 2" fi sed -e 's/'"$1"'/'"$2"'/g' "$file" > $TEMP_FILE1 mv $TEMP_FILE1 "$file" return } # end of search_and_replace # Recursive Directory Traverser # Author: Kaz Kylheku # Date: Feb 27, 1999 # Copyright 1999 function recurse() { # Function parameter usage: # $1 directory to search # $2 pattern to search for # $3 command to execute # $4 secret argument for passing down path if [ "$1" = "" ]; then error_exit "recurse: missing argument 1" fi if [ "$2" = "" ]; then error_exit "recurse: missing argument 2" fi if [ "$3" = "" ]; then error_exit "recurse: missing argument 3" fi local file local path if [ "$4" = "" ] ; then path="${1%/}/" else path="$4$1/" fi if cd "$1" ; then for file in $2; do if [ -f "$file" -o -d "$file" ]; then eval "$3" fi done for file in .* * ; do if [ "$file" = "." -o "$file" = ".." ] ; then continue fi if [ -d "$file" -a ! -L "$file" ]; then recurse "$file" "$2" "$3" "$path" fi done cd .. fi } # ------------------------------------------------------------------ # Program starts here # ------------------------------------------------------------------ ##### Initialization And Setup ##### ## Set file creation mask so that all files are created with 600 ## permissions. ## #umask 066 # Trap TERM, HUP, and INT signals and properly exit trap "signal_exit TERM" TERM HUP trap "signal_exit INT" INT ## Create temporary file(s) # make_temp_files ##### Command Line Processing ##### # if at least one argument is required... if [ $# -eq 0 ]; then echo "This is ${PROGNAME} ${VERSION}" usage clean_up exit 1 fi # Note that we use `"$@"' to let each command-line parameter expand to # a separate word. The quotes around `$@' are essential! We need # GETOPT_TEMP as the `eval set --' would nuke the return value of # getopt. GETOPT_TEMP=$(getopt -o +te:h --long test,extension:,help,version -n "$PROGNAME" -- "$@") if [ $? != 0 ] ; then error_exit "Error parsing command line. Terminating..." fi # Note the quotes around `$GETOPT_TEMP': they are essential! eval set -- "$GETOPT_TEMP" # no error checking necessary; sanity of command line and required # arguments has been checked by getopt program ext="*"; testmode=0; while true ; do case $1 in -t|--test) echo "TEST MODE" ; testmode=1; shift ;; -e|--extension) echo "search for extension: $2" ext=$2 shift 2 ;; -h|--help) helptext ; graceful_exit ;; --version) echo "${PROGNAME} ${VERSION}" ; shift ;; --) shift ; break ;; *) # should be impossible to reach: getopt should have caught # an error error_exit "This should not have happened; unknown option '$1'. Terminating..." ;; esac done unset GETOPT_TEMP # processing remaining arguments for the client if [ $# -ne 0 ]; then echo "Searching for: $@" fi ##### Main Logic ##### recurse `/bin/pwd` "*.$ext" "search_and_replace $1 $2" graceful_exit # end of search_and_replace.sh
| Attachment | Size |
|---|---|
| search_and_replace.sh.zip | 3.54 KB |









Post new comment