7

I'm trying to write a script that searches a directory for files and greps for a pattern. Something similar to the below except the find expression is much more complicated (excludes particular directories and files).

#!/bin/bash
if [ -d "${!#}" ]
then
    path=${!#}
else
    path="."
fi

find $path -print0 | xargs -0 grep "$@"

Obviously, the above doesn't work because "$@" still contains the path. I've tried variants of building up an argument list by iterating over all the arguments to exclude path such as

args=${@%$path}
find $path -print0 | xargs -0 grep "$path"

or

whitespace="[[:space:]]"
args=""
for i in "${@%$path}"
do
    # handle the NULL case
    if [ ! "$i" ]
    then
        continue
    # quote any arguments containing white-space
    elif [[ $i =~ $whitespace ]]
    then
        args="$args \"$i\""
    else
        args="$args $i"
    fi
done

find $path -print0 | xargs -0 grep --color "$args"

but these fail with quoted input. For example,

# ./find.sh -i "some quoted string"
grep: quoted: No such file or directory
grep: string: No such file or directory

Note that if $@ doesn't contain the path, the first script does do what I want.


EDIT : Thanks for the great solutions! I went with a combination of the answers:

#!/bin/bash

path="."
end=$#

if [ -d "${!#}" ]
then
    path="${!#}"
    end=$((end - 1))
fi

find "$path" -print0 | xargs -0 grep "${@:1:$end}"

1 Answer 1

8

EDIT:

Original was just slightly off. No removal is to be done if the last argument is not a directory.

#!/bin/bash
if [ -d "${!#}" ]
then
    path="${!#}"
    remove=1
else
    path="."
    remove=0
fi

find "$path" -print0 | xargs -0 grep "${@:1:$(($#-remove))}"
Sign up to request clarification or add additional context in comments.

1 Comment

+1 I learned 2 things from your answer, and I use bash for over 10 years extensively

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.