在zsh中按组合并文件:104个文件每10个一组合并的实现方法
zsh 批量按组合并文件方案
完整脚本示例
# 1. 将文件按需求排序后存入数组 # 若文件名是数字排序(如file1, file2...)用下面这行 files=(*(Nn)) # 若按默认字典序排序,用这行:files=(*(N)) # 2. 设置分组参数 group_size=10 total_files=${#files[@]} # 计算总组数(向上取整) num_groups=$(( (total_files + group_size - 1) / group_size )) # 3. 循环合并每组文件 for ((i=1; i<=num_groups; i++)); do # 计算当前组的起始/结束索引 start=$(( (i-1)*group_size + 1 )) end=$(( i*group_size )) # 最后一组的结束索引不超过总文件数 (( end > total_files )) && end=$total_files # 执行合并命令 cat ${files[$start,$end]} > "newfile$i" echo "已合并第$i组:从第$start个到第$end个文件,生成newfile$i" done
逐行详细解释
文件数组定义:
*(Nn)是zsh的glob限定符:N:开启nullglob,如果当前目录没有匹配的文件,不会返回*本身,而是空数组,避免报错n:开启数字排序,比如file10会排在file2后面(默认字典序会把file10放file2前面)
- 执行
echo ${files[@]}可以预览排序后的文件列表,确认顺序符合要求
分组参数计算:
group_size=10:可以根据需求修改每组的文件数量${#files[@]}:获取数组的长度,也就是总文件数$(( (total_files + group_size - 1) / group_size )):这是整数运算里的向上取整公式,比如104个文件,(104+10-1)/10=113/10=11(zsh整数除法会舍去小数部分),正好得到11组
循环逻辑:
for ((i=1; i<=num_groups; i++)):zsh支持C风格的for循环,从1遍历到总组数start=$(( (i-1)*group_size + 1 )):计算当前组的第一个文件在数组中的索引(zsh数组索引从1开始)end=$(( i*group_size )):计算当前组的最后一个文件索引(( end > total_files )) && end=$total_files:处理最后一组,比如第11组的end原本是110,但总文件只有104,所以把end改成104cat ${files[$start,$end]} > "newfile$i":合并当前组的文件到对应的newfile,数组切片${files[$start,$end]}会自动展开成该范围内的所有文件名,即使文件名有空格也能正确处理
测试建议
在正式执行合并前,可以把cat改成echo cat,这样会打印出要执行的命令,确认每组的文件范围正确:
echo cat ${files[$start,$end]} > "newfile$i"
扩展说明
- 如果需要按修改时间排序合并,把数组定义改成:
files=(*(Nom)),其中o表示排序,m表示按修改时间(最新的在前,要最旧的在前用Om) - 如果需要匹配特定后缀的文件(比如只合并.txt文件),把
*改成*.txt即可,比如files=(*.txt(Nn))
内容的提问来源于stack exchange,提问作者CosmicSpittle
相关产品推荐
相关产品推荐

