如何使用bash/awk/sed从多文本文件提取指定列并合并输出?
实现方案
方案1:类Unix系统(Linux/macOS) awk 一键实现
直接运行以下命令即可,把命令里的./file*.txt换成你实际的输入文件路径,./output_dir/merged.txt换成你要保存的目标文件路径:
awk ' BEGIN { FS = "\t" OFS = "\t" } FNR == 1 { colname = FILENAME sub(/\.[^.]*$/, "", colname) colname = colname "_numreads" cols[++file_cnt] = colname next } { key = $0 sub(/\t.*/, "", key) data[key][file_cnt] = $4 } END { printf "#rname" for (i=1; i<=file_cnt; i++) printf OFS cols[i] print "" for (key in data) { printf key for (i=1; i<=file_cnt; i++) printf OFS data[key][i] print "" } } ' ./file*.txt > ./output_dir/merged.txt
说明:
- 自动识别所有输入文件的文件名生成对应列名,支持任意数量的输入文件
- 自动按
#rname字段合并,即使不同文件的行顺序不一致也能正确匹配 - 默认按制表符分隔输入输出,符合你提供的文件格式
方案2:Python 跨平台实现
Windows、Linux、macOS都可以用,把以下代码保存为merge_reads.py,修改开头的输入输出路径后运行即可:
import os from collections import defaultdict # 配置部分,按需修改 INPUT_FILES = ["./file1.txt", "./file2.txt"] # 你的输入文件路径列表 OUTPUT_PATH = "./output_dir/merged.txt" # 目标输出文件路径 SEP = "\t" # 文件的列分隔符,你这里是制表符所以不用改 # 处理逻辑 data = defaultdict(dict) col_names = [] for fp in INPUT_FILES: base_name = os.path.basename(fp).rsplit(".", 1)[0] col_name = f"{base_name}_numreads" col_names.append(col_name) with open(fp, encoding="utf-8") as f: next(f) # 跳过表头 for line in f: if not line.strip(): continue parts = line.rstrip("\n").split(SEP) rname = parts[0] numreads = parts[3] data[rname][col_name] = numreads # 写入输出 with open(OUTPUT_PATH, "w", encoding="utf-8", newline="") as f: # 写表头 f.write(f"#rname{SEP}{SEP.join(col_names)}\n") # 写内容 for rname, vals in data.items(): row = [rname] + [vals.get(col, "") for col in col_names] f.write(f"{SEP.join(row)}\n")
内容的提问来源于stack exchange,提问作者abs
相关产品推荐
相关产品推荐

