Removing final bash script argument
arguments, bash, shell
Solution
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))}"
Problem
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}" ```