You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

readarray结合find与sort命令返回数组长度超出预期的问题

问题根因

核心是命令间的分隔符规则不匹配,外加数组遍历写法存在疏漏:

  • sort未做NUL分隔适配
    你给find加了-print0参数,本意是用ASCII空字符(NUL,\0)分隔文件名,兼容带空格、换行的特殊文件名,但管道后的sort -r默认以换行符作为条目拆分、输出的分隔规则,完全不识别NUL分隔符:既不会按NUL拆分find传入的文件列表,排序完成输出结果时也只会在末尾追加换行符,不会输出NUL分隔符。
    这种情况下sort输出的字节流里仅包含1个NUL,末尾多了一个多余换行,完全不符合readarray按NUL拆分的读取预期,自然会读入异常元素。
  • 数组遍历未加双引号,隐藏了异常元素
    你写的遍历逻辑for r in ${matches[@]}没有给数组加双引号,shell会自动对数组元素做单词拆分,把元素内携带的换行符当成单词分隔符处理,多出来的换行元素被拆成了无显示内容的空值,才会出现数组长度显示异常、但打印仅能看到2条结果的现象。你贴出的typeset -p结果已经能佐证这个问题:[1]=$'\n'就是sort输出末尾追加的换行被readarray当成独立元素读入了数组。
修复方案
  1. 给sort加-z(--zero-terminated)参数,开启NUL分隔模式,和前面find的-print0、后面readarray的-d ''规则完全对齐,全程用NUL作为分隔符,彻底避免特殊文件名解析错误:
readarray -td '' matches < <(find /var/backup/web30/ -regextype egrep -regex '.*/web30_2022-07-14_[0-9]{2}-[0-9]{2}.tar.gz' -print0 | sort -rz)
  1. 遍历数组时必须给数组变量加双引号,禁止shell自动拆分内容:
for r in "${matches[@]}"; do
  echo "match: $r"
done
额外优化建议

如果你的最终需求是提取指定日期下最后修改的备份文件,不需要靠文件名排序,直接按文件实际修改时间倒序取结果准确率更高:

readarray -td '' matches < <(find /var/backup/web30/ -regextype egrep -regex '.*/web30_2022-07-14_[0-9]{2}-[0-9]{2}.tar.gz' -print0 | xargs -0 ls -1t)
# 最新修改的文件直接取 ${matches[0]} 即可

内容的提问来源于stack exchange,提问作者C4pt4inC4nn4bis

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 17:15:41