我使用以下命令来检索名称包含的文件数sv
或json
远程服务器中给定目录中的文件数:
nbs_files=`ssh -q -i ${sshkey} ${user}@${server} "find ${path}/ -maxdepth 1 -mindepth 1 -type f -name '*sv*' -o -name '*.json' -exec basename {} \; | wc -l"`
此命令仅返回文件数.json
,而sv
名称中包含 的文件存在于${path}
.
当我删除该-o -name '*.json'
部分时,该命令运行良好,并返回名称中包含“sv”的文件数。
有谁知道如何修改命令以检索sv
名称中包含的文件以及带有扩展名的文件.json
?
答案1
问题在于find
表达式中的 and/or 运算符优先级。具体来说,相邻测试之间的隐式 AND 的优先级高于-o
两个名称测试之间的 OR ( ) 。因此测试表达式被解析为:
-maxdepth 1 -mindepth 1 -type f -name '*sv*'
OR
-name '*.json' -exec basename {} \;
...并且由于 是-name '*.json'
唯一与 属于同一分支的一部分-exec
,因此-exec
仅针对 json 文件运行。
解决方案是在测试周围使用显式括号来覆盖正常优先级-name
:
nbs_files=$(ssh -q -i ${sshkey} ${user}@${server} "find ${path}/ -maxdepth 1 -mindepth 1 -type f '(' -name '*sv*' -o -name '*.json' ')' -exec basename {} \; | wc -l")
顺便说一句,我还冒昧地将反引号替换为$( )
——它们是更现代的选项,更容易阅读,并且没有反引号所具有的奇怪的转义异常。看这个问题和Bash 常见问题解答#82。