Ubuntu 18.04中find结果的稳定分区排序实现需求
解决大型目录下优先输出含指定子串文件的高效方法
我明白你在处理大型目录时的痛点——重复遍历或者用临时文件确实会拖慢效率,这里有个只需要一次目录遍历的高效方案,完全符合你的需求:
核心思路
我们通过一次find遍历,给符合条件的文件加优先级标记,然后利用sort的多关键字排序规则,先按优先级分组,再按文件名字母顺序排序,最后去掉标记即可。
直接可用的命令(以子串foo为例)
find . -type f | awk '/foo/ {print "1\t"$0; next} {print "2\t"$0}' | sort -k1,1n -k2,2 | cut -f2-
分步解释
- 一次遍历目录:
find . -type f只执行一次,避免重复IO,特别适合大型目录场景。 - 添加优先级标记:用
awk给包含foo的文件名前加1\t,其余加2\t——1代表高优先级,2是普通优先级。 - 多关键字排序:
sort -k1,1n -k2,2先按第一列的数字排序(保证高优先级组在前),再按第二列的原文件名做字母排序(保证每组内部有序)。 - 去除标记:
cut -f2-去掉前面的优先级标记,得到最终的有序结果。
适配变量子串的版本
如果你的目标子串是动态的(比如存放在变量里),可以用这个灵活版本:
SEARCH_SUBSTR="foo" find . -type f | awk -v str="$SEARCH_SUBSTR" '$0 ~ str {print "1\t"$0; next} {print "2\t"$0}' | sort -k1,1n -k2,2 | cut -f2-
处理特殊文件名的情况
如果你的文件名里包含制表符(虽然很少见),可以换用ASCII控制字符作为分隔符避免冲突:
find . -type f | awk -v sep=$'\x01' '/foo/ {print "1" sep $0; next} {print "2" sep $0}' | sort -t$'\x01' -k1,1n -k2,2 | cut -d$'\x01' -f2-
效果验证
针对你给出的示例输入:
./aaaaaafoo ./bbbbbbfoo ./ccccccbar
执行命令后会输出:
./aaaaaafoo ./bbbbbbfoo ./ccccccbar
完全满足“含foo的文件优先,整体保持字母顺序”的要求。
内容的提问来源于stack exchange,提问作者Sebastián Mestre
相关产品推荐
相关产品推荐

