如果已经回答,我很抱歉,但如果是,我找不到合适的搜索字词。
我正在尝试为find命令动态定义搜索词(基于用户定义的设置):
# reading user settings results in array of filename patterns to delete:
patterns=("*.url" "*.html")
for i in ${patterns[@]}; do
find . -iname $i -delete
done
如果我echo
该命令,结果字符串看起来是正确的,例如
find . -iname "*.url" -delete
find . -iname "*.html" -delete
我知道我错过了一些显而易见的东西,但我没有尝试过。
如果有帮助,我正在使用Bash 4.4.5。
---------------- EDIT -----------------
我要感谢Charles Duffy和l'L'l以获得正确的解决方案。我很难将数据字符串中的引号与引用的变量包围在一起,并且无法同时引用这两个变量。
获得的经验:总是引用shell变量。
答案 0 :(得分:5)
The answer by l'L'l是一个不错的选项,但是通过在一个命令行中传递所有模式只调用find
一次,让它更高效一点:
patterns=("*.url" "*.html")
find_pat=( )
for i in "${patterns[@]}"; do
find_pat+=( -o -name "$i" )
done
find . -iname '(' "${find_pat[@]:1}" ')' -delete
运行时,将调用:
find . -iname '(' -name '*.url' -o -name '*.html' ')' -delete
...因此,一次性删除所有与 <{em> *.url
或*.html
匹配的文件。
注意:
patterns
数组),在数组扩展时(所以我们遍历globs本身而不是他们的结果),并且扩展到find
命令(所以我们传递find
文字模式语法,而不是扩展该语法的结果。)-o
添加到find_pat
数组中,然后从第二个元素(数组为0索引)进行扩展,从而跳过该初始-o
。这里使用的语法是parameter expansion。答案 1 :(得分:3)
您需要双引号变量:
for i in "${patterns[@]}"; do
find . -iname "$i" -delete
...
这将防止通配和分词。
您始终可以在https://www.shellcheck.net/检查您的脚本是否也有错误...