: ########################################################################## # Title : rgrep - recursive grep # Author : Heiner Steven # Date : 1996-02-12 # Category : File Utilities # Requires : egrep, find [xargs] # SCCS-Id. : @(#) rgrep 1.7 06/03/28 ########################################################################## # Description # This script basically executes the following command: # find . -print | xargs egrep searchstring # # It tries to figure out additional arguments, and constructs the # pipeline above. Care is taken to correctly handle files and # directories with whitespace characters. # Caveats # o The argument relaying for "egrep" and "find" assumes that these # commands accept the same arguments as the Solaris 8 version ########################################################################## PN=`basename "$0"` # Program name VER='1.7' ########################################################################## # Configuration section # # grep and grep options (taken from Solaris 2.8 "egrep" manual page) # GREP=egrep GREPFLAGS=bchilnsv # Option flags GREPARGS=e:f: # Switches requiring an argument # # find and options (without and with argument) # (taken from Solaris 2.8 "find" manual page) # findtype= # Set to disable auto-configuration {default|posix|gnu} FIND=find FINDFLAGS="-depth -follow -local -ls -mount -nogroup - nouser -print \ -prune - xdev" FINDARGS="-atime -cpio -ctime -exec -fstype -group -inum -links -mtime \ -name -cpio -newer -ok -perm -size -type -user" # End of configuration section ########################################################################## FindOpts="-follow -type f" GrepOpts= Usage () { echo >&2 "$PN - recursive grep, $VER usage: $PN [-hd] [grep_opts | find_opts] SearchString [file | directory] ... -h: print this usage summary -d: debugging output grep_opts: Options for $GREP (the default is \"$GrepOpts\") find_opts: Options for find (the default is \"$FindOpts\"). Options consisting of a single letter are considered to be $GREP options, longer options are interpreted as find options." exit 1 } Msg () { for i do echo "$PN: $i" >&2 done } Fatal () { Msg "$@"; exit 1; } True () { return 0; } False () { return 1; } Args= Debug=False # True/False while [ $# -gt 0 ] do case "$1" in --) shift; break;; -h) Usage;; -d) Debug=True;; -??*) # Long find option case "$FINDARGS" in *"$1"*) $Debug && echo >&2 "$1 is find option with argument" Args="${Args:+$Args }$1 \"$2\"" shift 2 continue ;; esac case "$FINDFLAGS" in *"$1"*) $Debug && echo >&2 "$1 is find option without argument" Args="${Args:+$Args }$1" shift continue ;; esac ;; -*) # Short grep option if getopt "$GREPARGS" "$1" "$2" >/dev/null 2>&1 then $Debug && echo >&2 "$1 is grep option" GrepOpts="${GrepOpts:+$GrepOpts }$1 \"$2\"" shift elif getopt "$GREPFLAGS" "$1" >/dev/null 2>&1 then $Debug && echo >&2 "$1 is grep option" GrepOpts="${GrepOpts:+$GrepOpts }$1" else Fatal "unknown option: $1" fi ;; *) break;; # Search string esac shift done [ -n "$Args" ] && FindOpts="$Args" [ $# -lt 1 ] && Usage Search="$1"; shift [ $# -lt 1 ] && set -- . # Default search directory $Debug && set -x ########################################################################## # We could use the sequence "find . -exec grep {} \;" which is portable # to almost all systems, but it is very slow because one "grep" process # is started for each file. # # The command line "find . -print | xargs grep" is much faster and # fairly portable, but does not handle whitespace in directory or file # names correctly. # POSIX and GNU have solved that problem differently: # POSIX: find . -exec grep {} + # (internal xargs) # GNU: find . -print0 | xargs -0 grep # (delimiter is zero) # # To get the fastest possible method we are prepared to select one of # the two methods. If none of them is available, we use the slow (but # safe) command line. ########################################################################## if [ -z "$findtype" ] then #findtype= # {default|posix|gnu} # Guess type of "find" command by looking at the operating system. # This is faster than actually trying "find" features. case `uname | tr '[a-z]' '[A-Z]'` in SUNOS) case `uname -r` in 5*) findtype=posix;; # Solaris 4*) findtype=default;; # SunOS esac;; LINUX) findtype=gnu;; esac findtype= # DEBUG # Unknown operating system: try which of the features work. This is very # slow. if [ -z "$findtype" ] then if find . -type d -name "." -exec echo {} + >/dev/null 2>&1 then findtype=posix else if find . -type d -name "." -print0 >/dev/null 2>&1 then findtype=gnu else findtype=default fi fi fi fi #echo >&2 "DEBUG: findtype=$findtype" find='"$FIND" "$@" '$FindOpts grep='"$GREP" '$GrepOpts' "$Search" /dev/null' case "$findtype" in posix) cmd=$find' -exec '$grep' {} +';; gnu) cmd=$find' -print0 | xargs -0 '$grep;; *) cmd=$find' -exec '$grep' \;';; esac eval "$cmd"