This is an example of my filesystem:
- /code/
- internal/
- dev/
- main/
- public/
- dev/
- main/
- release/
- tools/
- internal/
/code/internal/dev/, /code/public/dev/ and /code/tools/ contain subdirectories for multiple projects. I work almost exclusively in the dev branches of /code/internal/ and /code/public/, and often I want to search for a text string in those directories along with /code/tools/ (which has no branches). In these instances I run a command like this:
grep -I -r FooBar /code/internal/dev/ /code/public/dev/ /code/tools/
Additionally, sometimes I am only interested in certain file types. Then the command becomes:
grep -I -r FooBar /code/internal/dev/ /code/public/dev/ /code/tools/ | grep .c:\|.h:
I usually forget this command between usages and end up having to relearn it. To alleviate that problem, I created a script - which I would appreciate feedback on :)
search() {
local t
local OPTIND
local pattern
local files
local types
if [ $1 = --help ]; then
echo "Usage: search [OPTION] ... PATTERN [FILE] ..."
echo "Search for PATTERN in each FILE."
echo "Example: search -t c -t h 'hello world' /code/internal/dev/ /code/public/dev/"
echo
echo "Output control:"
echo " -t limit results to files of type"
return
fi
while getopts ":t:" opt; do
case $opt in
t) t=(${t[@]} $OPTARG);; # create an array
esac
done
shift $((OPTIND-1))
pattern=$1
files=${@:2}
if [ -n "$t" ]; then
# cast the array to a string
types=${t[@]}
# convert the string to a pattern usable by grep
# example: "c h" becomes ".c:\|.h:"
types=.${types// /':\|.'}:
grep -I -r $pattern $files | grep $types
else
grep -I -r $pattern $files
fi
}
With this and a couple more shortcut scripts, I can (relatively) quickly find anything I'm looking for:
search-all-code() {
search $@ /code/internal/dev/ /code/public/dev/ /code/tools/
}
Aside: I realize some versions of grep support --include
and --exlude
options, but the version of grep I'm stuck with doesn't.