如何递归拼接指定类型文件并自定义部分文件的首尾排序
解决方案
问题核心原因
你原本的写法出现重复是因为*.txt通配符会匹配当前目录下所有.txt后缀文件,包含你已经单独指定的header.txt、interesting.txt、footer.txt,且默认不递归子目录,无法匹配到dir/lnln.txt这类子目录文件。
方案1:Bash 极简写法(适用绝大多数Linux发行版)
依赖Bash的extglob(扩展通配符)和globstar(递归通配)特性,一行即可完成:
# 先开启必要的Shell特性(可写到.bashrc永久生效) shopt -s extglob globstar # 拼接顺序:指定头文件 → 所有未被指定为头/尾的txt文件(递归所有子目录) → 指定尾文件 cat header.txt interesting.txt **/!(@(header|interesting|footer)).txt footer.txt
- 如果你需要保留子目录里的
header.txt/footer.txt,只排除顶层的几个指定文件,可以调整通配符为:cat header.txt interesting.txt !(@(header|interesting|footer)).txt **/*.txt footer.txt
方案2:全兼容通用写法(适用所有Shell、支持带特殊字符的文件名)
如果需要兼容POSIX标准Shell,或者要处理带空格、换行的文件名,用find+排序逻辑实现:
find . -type f -name "*.txt" -print0 | awk -v RS='\0' ' BEGIN { # 自定义优先级:数值越小排越靠前,尾文件设置大数值排最后 pri["./header.txt"] = 1 pri["./interesting.txt"] = 2 pri["./footer.txt"] = 999 } { print (pri[$0] ? pri[$0] : 500) "\0" $0 } ' | sort -z -n | cut -z -f2- | xargs -0 cat
- 所有未在优先级里定义的文件默认按500优先级排序,会自动排在头文件之后、尾文件之前
- 全程用空字符作为分隔符,不会因为文件名含空格、特殊符号出错
内容的提问来源于stack exchange,提问作者Ross
相关产品推荐
相关产品推荐

