#!/bin/bash # # Syntax: grepdo [-h] [-a] [-w] [-u] command regexp [file [...]] # # Purpose: Performs a grep on the given files and runs the given command # on each file that matches the given regular expression regexp. # If only one input argument is specified, the grep is performed # on all files in the current directory. # If the -a flag is specified the command is run on all matching # files at once. Otherwise, it is called separately for each matching # file. # If the option -w is specified, grepem searches for string as a # word. # By default grepdo does a case-insenstive grep. However, if the # option -u is specified, grepem distinguishes between upper # and lower case letters. # Created: Aug 6, 2007 by Bart De Schutter # Last revised: Oct 19, 2007 by Bart De Schutter # # See http://www.deschutter.info/util/scripts.html for the latest version of # this script. # Status: public # Category: files # # Process input arguments. # case_string="-i" word_string="" all_at_once=0 while getopts :hawu option do case "$option" in h) sed '/^$/q;/^#!/d;s/^# //;s/^#//' $0 >&2 exit 1 ;; a) all_at_once=1;; w) word_string="-w";; u) case_string="";; \?) echo >&2 echo >&2 "Unknown option: $OPTARG" echo >&2 sed '/^$/q;/^#!/d;s/^# //;s/^#//' $0 >&2 exit 1 ;; esac done shift $(($OPTIND-1)) if [ $# -le 1 ]; then echo >&2 echo >&2 "ERROR: ${0##*/} requires at least 2 input arguments." echo >&2 sed '/^$/q;/^#!/d;s/^# //;s/^#//' $0 >&2 exit 1 fi command=$1 shift # # Perform grep and process files that match the given regexp. # if [ $all_at_once -eq 0 ] then declare -a lst if [ $# -eq 1 ]; then lst=( $(grep -l $case_string $word_string "$1" *) ) else lst=( $(grep -l $case_string $word_string "$@") ) fi if [ $? -eq 1 ] then echo "No files found that match the given regular expression." else for fil in "${lst[@]}" do eval "$command" "$fil" done fi else if [ $# -eq 1 ]; then lst=$(grep -l $case_string $word_string "$1" *) else lst=$(grep -l $case_string $word_string "$@") fi if [ ! -z "$lst" ] then # Do some processing in order to be able to deal with files that # contain a space or a # in their name. lst=$(echo "$lst" | sed -e 's/ /\\ /g;s/#/\\#/g' | tr "\n" " " ) eval "$command" $lst else echo "No files found that match the given regular expression." fi fi