使用find命令传入含文件的fdir数组时因sufx参数报错如何解决?
问题原因
核心问题来自两个错误点:
- 前置路径过滤的循环存在变量名笔误:判断条件中的
$arg属于未定义变量,原本需要校验的当前遍历对象$dpa没有被正确判断,导致非目录的文件路径被错误加入fdir数组 find命令参数顺序与匹配规则存在逻辑错误:-maxdepth是全局选项必须放在所有测试条件之前,同时-o逻辑或的优先级低于默认的-a逻辑与,不加括号的情况下后缀匹配规则完全不符合预期
解决方案
以下两种方案可单独使用,也可搭配使用覆盖所有场景:
方案1:修复前置过滤逻辑,从根源避免文件进入fdir数组
先修正路径过滤的循环逻辑,再调整find的参数规则即可:
for dpa in "$@"; do # 修正逻辑:不是目录 或者 已标记过的路径直接跳过 [[ ! -d $dpa || ${tag[mo:$dpa]} ]] && continue fdir+=("$dpa") tag[mo:$dpa]=1 done hn=21 # 后缀匹配加括号保证逻辑优先级,通配符加引号避免被shell提前展开 sufx=( \( -name "*.sh" -o -name "*.c" \) ) mxdpt=( -maxdepth 3 ) # 全局选项-maxdepth放在测试条件最前面 find "${fdir[@]}" "${mxdpt[@]}" -type f "${sufx[@]}" \ -exec head -v -n "$hn" '{}' +
方案2:兼容fdir中存在文件的场景
如果无法保证fdir的元素都是目录,可以拆分路径分别处理,完全避免find报错:
hn=21 sufx=( \( -name "*.sh" -o -name "*.c" \) ) mxdpt=( -maxdepth 3 ) # 拆分fdir中的目录和文件 dirs=() single_files=() for p in "${fdir[@]}"; do if [[ -d $p ]]; then dirs+=("$p") elif [[ -f $p ]]; then single_files+=("$p") fi done # 处理目录下的匹配文件 find "${dirs[@]}" "${mxdpt[@]}" -type f "${sufx[@]}" -exec head -v -n "$hn" '{}' + # 单独校验fdir中文件的后缀,符合要求就执行head for f in "${single_files[@]}"; do [[ $f == *.sh || $f == *.c ]] && head -v -n "$hn" "$f" done
内容的提问来源于stack exchange,提问作者Dilna
相关产品推荐
相关产品推荐

