如何用awk配合for循环提取目录文本文件数据生成CSV?
解决方案:用awk+for循环批量生成统计CSV
我明白你想批量处理目录里的文本文件,提取指定统计项生成CSV的需求——之前的代码问题主要出在match函数的用法和行号判断上,咱们来调整一下,用单个for循环结合awk就能搞定。
完整实现脚本
# 先清空输出文件(避免多次运行重复追加,不需要的话可以删掉这行) > Names.csv # 遍历目录下所有txt文件 for file in *.txt; do awk ' BEGIN { # 定义需要提取的行号和对应的统计项变量,方便后续修改 line_map[1] = "total_reads" line_map[3] = "unmapped_reads" line_map[4] = "unique_reads" line_map[5] = "multi_reads" } # 当处理到指定行号时,提取数字 FNR in line_map { # GNU awk写法:用match捕获连续数字串 if (match($0, /[0-9]+/, num_match)) { data[line_map[FNR]] = num_match[0] } # 兼容非GNU awk的写法(如果上面的报错,就换成下面这行) # data[line_map[FNR]] = $0; gsub(/[^0-9]/, "", data[line_map[FNR]]) } # 每个文件处理完成后执行输出 ENDFILE { # 从文件名提取Sample名称:去掉末尾的重复后缀 sample_name = FILENAME gsub(/_RepetitiveText_ToRemove\.txt$/, "", sample_name) # 仅在第一个文件处理时打印CSV表头 if (!header_printed) { print "Sample,Total_Reads,Uniquely_Mapped_Reads,Multi_Mapped_Reads,Unmapped_Reads" header_printed = 1 } # 输出当前文件的统计数据行 print sample_name "," data["total_reads"] "," data["unique_reads"] "," data["multi_reads"] "," data["unmapped_reads"] # 清空数据数组,避免下一个文件复用旧数据 delete data } ' "$file" >> Names.csv done
关键细节说明
- 文件名处理:用
gsub去掉文件名末尾固定的_RepetitiveText_ToRemove.txt后缀,得到干净的Sample名称。 - 数字提取:两种写法兼容不同awk版本——GNU awk可以用
match的捕获组直接抓数字,非GNU awk则通过去掉所有非数字字符来提取。 - 表头控制:用全局变量
header_printed确保表头只输出一次,不会每个文件都重复打印。 - 文件遍历:用
"$file"包裹文件名,避免文件名包含空格或特殊字符时出错。
注意事项
如果你的统计项对应的行号和我假设的(Total在第1行、Unmapped在第3行等)不一致,只需要修改BEGIN块里的line_map数组,把行号和对应的统计项变量对应好就行。
内容的提问来源于stack exchange,提问作者JVGen
相关产品推荐
相关产品推荐

