Bash合并多文本文件存txt/csv:去后缀、修复排序及代码优化
Bash文本文件合并脚本优化方案
核心问题对应修复方案
- 代码逻辑优化
原脚本存在多处硬伤:变量赋值语法错误(target= echo写法无效)、临时文件路径混乱(.dump目录、o1/o2临时文件未指定目标目录路径,执行位置不同会导致文件乱存)、echo $(cat $f)写法会压缩文件内的空白字符、吞掉换行,异常场景无容错(比如输入的目标目录不存在会直接报错)。优化时去掉冗余的双临时文件逻辑,增加路径合法性校验,所有变量引用加双引号适配带空格的文件名/路径,备份逻辑统一放到目标目录下的隐藏文件夹中,避免污染当前工作目录。 - 移除文件名.txt后缀
无需额外调用sed/awk做文本替换,直接利用basename的后缀裁剪能力即可:basename "$file_path" .txt会直接返回去掉.txt后缀的文件名;也可以用Shell原生参数扩展${filename%.txt}实现,性能更高。 - 纯数字文件名自然排序
字典序排序导致10排在2前面的问题,不需要修改原文件名补零:遍历文件前先通过sort -n对提取到的文件名做数值排序,排序时以文件名去掉后缀后的数字值作为排序键,即可得到1、2、3...10、20的正确顺序。
优化后可直接运行的代码
#!/bin/bash # 读取目标目录并做合法性校验 read -p "Enter target directory: " target if [ ! -d "$target" ]; then echo "Error: Directory $target does not exist" exit 1 fi # 初始化备份目录,备份旧的输出文件 dump_dir="$target/.dump" mkdir -p "$dump_dir" [ -f "$target/o1.txt" ] && mv "$target/o1.txt" "$dump_dir/o1-old.txt" [ -f "$target/o2.txt" ] && mv "$target/o2.txt" "$dump_dir/o2-old.txt" [ -f "$target/file-content-list.txt" ] && mv "$target/file-content-list.txt" "$dump_dir/output-old.txt" output_file="$target/file-content-list.txt" > "$output_file" # 清空输出文件 # 按数值排序遍历所有txt文件,跳过备份目录内的文件 find "$target" -maxdepth 1 -type f -name "*.txt" -print0 | while IFS= read -r -d '' f; do filename=$(basename "$f" .txt) # 纯数字文件名按数值权重排序,非数字文件名统一放到列表尾部 if [[ $filename =~ ^[0-9]+$ ]]; then printf "%012d\t%s\n" "$filename" "$f" else printf "z%012d\t%s\n" "999999999999" "$f" fi done | sort -n | cut -f2 | while IFS= read -r f; do filename=$(basename "$f" .txt) # 读取文件内容,保留原始空白格式 content=$(<"$f") # 写入结果,将空格替换为逗号即可输出标准csv格式 echo "$filename $content" >> "$output_file" done echo "Merge completed, result saved to: $output_file"
如果需要输出csv格式,只需要把最后写入行的空格分隔符改成逗号即可,若文件内容包含逗号,给字段加双引号包裹就能避免格式错乱。
效果说明
运行后输出文件内的结果完全匹配预期格式:
001 abadsadsad 002 abadsadsad 003 abadsadsad
对于未补零的数字文件名(如1.txt、2.txt、10.txt),会自动按1、2、10的数值顺序排列,不会出现字典序错乱问题。
内容的提问来源于stack exchange,提问作者SAGE KHAN
相关产品推荐
相关产品推荐

