如何在Bash脚本中使用变量作为find命令的过滤参数
解决复杂find过滤条件传递的Bash脚本问题
你的核心问题在于用单个变量存储多参数的过滤条件,Bash的字符串分词会破坏参数的原始结构(比如带引号的路径模式会被拆成普通字符)。改用数组来存储过滤参数就能解决这个问题,修改后的脚本如下:
#!/bin/bash DIRECTORY="$1" shift # 移除第一个目录参数,剩余所有参数作为过滤条件 FILTER=("$@") if [ ${#FILTER[@]} -eq 0 ]; then find "$DIRECTORY" -type f -delete else find "$DIRECTORY" -type f \( "${FILTER[@]}" \) -delete fi
为什么原来的写法失效?
当你执行./myscript.sh "src" "-name *.pb.go -and -not -path 'src/vendor/*'"时,脚本里的$FILTER会被Bash分词成多个独立片段:-name、*.pb.go、-and、-not、-path、'src/vendor/*'。这里的单引号会被当成普通字符而非引号,find会尝试匹配带单引号的路径'src/vendor/*',自然找不到符合条件的文件。
如果给$FILTER加双引号,整个字符串会被当成一个参数传给find,find无法识别"-name *.pb.go -and -not -path 'src/vendor/*'"这个完整字符串作为合法选项,所以返回空结果。
正确的调用方式
不需要把所有过滤条件用双引号包裹,直接按find的原生参数格式传递即可:
./myscript.sh src -name '*.pb.go' -and -not -path 'src/vendor/*'
如果你的Shell不会展开*.pb.go这类通配符(比如Zsh默认不展开,或Bash开启了noglob),也可以省略单引号:
./myscript.sh src -name *.pb.go -and -not -path src/vendor/*
数组"${FILTER[@]}"会保留每个参数的边界,把过滤条件原封不动地传递给find,完美适配复杂的多条件过滤场景。
内容的提问来源于stack exchange,提问作者Woody1193
相关产品推荐
相关产品推荐

