如何添加可选的分组参数列表来查找?
例如,使用一组基本参数来定义将始终找到的文件,而不管指定了哪些其他变量条件。
# args to find any files ending _count or _scan
._. fargs=( -type f -name '*_count' -o -name '*_scan' )
._. cd /sys/fs/ext4/sda1
._. find . \( "${fargs[@]}" \) 2> /dev/null
./mb_min_to_scan
./errors_count
./mb_max_to_scan
./msg_count
./warning_count
添加可选的附加参数
._. fpterm=warning
._. fpterm2=max
._. fANDargs=( -ipath "*$fpterm*" -o -ipath "*$fpterm2*" )
应用括号中的可选参数以使用以下形式执行查找:( a 或 b 或 c )和( d 或 e 或 f )
._. find . \( "${fargs[@]}" \) \( "${fANDargs[@]}" \) 2> /dev/null
./dm-1/mb_max_to_scan
./dm-1/warning_count
./dm-0/mb_max_to_scan
./dm-0/warning_count
./sda1/mb_max_to_scan
./sda1/warning_count
但是当可选的 arg 数组为空时,它会停止满足其他条件,并且根本找不到文件:
._. fANDargs=()
._. find . \( "${fargs[@]}" \) \( "${fANDargs[@]}" \) 2> /dev/null
._.
空括号导致问题:
._. find . \( "${fargs[@]}" \) \( \) 2> /dev/null
._.
而通常,一个空的 arg 数组不会阻止满足其他条件:
._. fANDargs=()
._. echo "${fANDargs[@]}"
._. find . \( "${fargs[@]}" \) "${fANDargs[@]}" 2> /dev/null
...
./sda1/mb_min_to_scan
./sda1/errors_count
./sda1/mb_max_to_scan
./sda1/msg_count
./sda1/warning_count
因此,如果仅当可选 args 数组不为空时才可以添加方括号,则该命令可能会起作用。
但是如何有条件地添加括号呢?
将括号添加到数组时似乎不起作用,例如:
._. fpterm=warning
._. fANDargs=()
._. [ ! -z $fpterm ] && fANDargs+=( '\(' -ipath "*$fpterm*" '\)' )
._. echo "${fANDargs[@]}"
\( -ipath *warning* \)
._. find . \( "${fargs[@]}" \) "${fANDargs[@]}" 2> /dev/null
._.
你在这里双引号。尝试仅一层:
(你也应该在 中使用引号
[ ! -z "$fpterm" ]
)通常,您在数组赋值中使用单词的方式与在命令中直接使用它们的方式完全相同。与引号一起使用
"${array[@]}"
(如您所做的那样)将扩展为数组的内容而无需进一步修改。(这是人们似乎经常出错的部分,他们似乎期望 shell 处理扩展结果的引号。事实并非如此,它更像是这里的“普通”编程语言。只要你使用引号来获取摆脱分裂+球的滋扰。)
当然,这里的背景是,
find
它本身想要看到的只是原样的括号(作为不同的参数)。它不需要看到引号,但shell需要它们,因为括号是特殊字符,是 shell 语法的一部分。所以你可以somecmd { foo bar }
不带引号使用,但你确实需要在somecmd \( foo bar \)
.顺便说一句,GNU find 警告一组空括号:
而且,好吧,从逻辑上讲,无论如何这似乎很奇怪。我的第一直觉是说空括号必须评估为虚假,这将
find \( whatever \) \( \)
永远不匹配。但它也可以被解释为真实的,这似乎是 Busybox 所做busybox find . \( \) -name '*.txt'
的,与busybox find . -name '*.txt'
.