删除 Bash 脚本的最后一个参数。

7
我正尝试编写一个脚本,搜索目录中的文件并使用grep命令查找特定模式的内容。与下面示例类似,但我的find表达式更加复杂(排除特定目录和文件)。请看以下代码:

```

find directory -not \( -path "exclude_directory" -prune \) -type f ! -name "exclude_file" -print0 | xargs -0 grep pattern

```

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

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

显然,以上方法无法生效,因为"$@"仍包含路径。我尝试了构建参数列表的各种变体,例如迭代所有参数来排除路径。
args=${@%$path}
find $path -print0 | xargs -0 grep "$path"

或者

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"

但是这些方法在输入内容带有引号时会失效。例如:

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

请注意,如果$@中不包含路径,则第一个脚本确实可以实现我的目标。
编辑:感谢提供的出色解决方案!我采用了这些答案的结合。
#!/bin/bash

path="."
end=$#

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

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

8

编辑:

原文略有误,如果最后一个参数不是目录,则无需删除。

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

find "$path" -print0 | xargs -0 grep "${@:1:$(($#-remove))}"

1
+1 我从你的答案中学到了两件事情,而我已经广泛地使用 bash 超过 10 年了。 - Tino

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接