如何根据i值匹配xyz文件与数据文件并提取对应行的前三列?
实现方法
你可以用Python快速实现这个需求,全程不需要依赖固定间隔规则,完全靠i值精准匹配,避免缺行错位问题。
第一步:提取所有xyz文件中的i值
先遍历目标目录下的所有xyz文件,读取每个文件的第二行提取i值,存为集合(查询速度比列表快很多)。
第二步:匹配长数据文件并输出结果
逐行读取长数据文件,仅保留Step列值在i值集合中的行,取前三列写入新文件。
Python示例代码
import os # -------------------------- 按需修改以下参数 -------------------------- xyz_dir = "./xyz_files" # 存放xyz文件的目录路径 long_data_path = "./long_data.txt" # 长数据文件路径 output_path = "./matched_result.txt" # 输出文件路径 long_data_sep = "\s+" # 长数据文件的列分隔符,默认是任意空白符,csv可改成"," i_extract_rule = lambda line: int(line.strip().split()[-1]) # 从xyz第二行提取i的规则,默认取行最后一个数值 # -------------------------------------------------------------------- # 提取所有i值 i_set = set() for filename in os.listdir(xyz_dir): if filename.endswith(".xyz"): with open(os.path.join(xyz_dir, filename), "r") as f: # 跳过第一行,读第二行 f.readline() second_line = f.readline() i_val = i_extract_rule(second_line) i_set.add(i_val) # 匹配长数据并输出 with open(long_data_path, "r") as f_in, open(output_path, "w") as f_out: # 如果长数据有表头,先读表头写入输出文件,不需要的话可以注释掉下面两行 header = f_in.readline() f_out.write("\t".join(header.strip().split(long_data_sep)[:3]) + "\n") # 逐行匹配 for line in f_in: line = line.strip() if not line: continue cols = line.split(long_data_sep) step_val = int(cols[0]) # 假设Step列是第一列,不是的话改下标即可 if step_val in i_set: # 取前三列写入,分隔符按需改成逗号或空格 f_out.write("\t".join(cols[:3]) + "\n")
说明:如果你的xyz文件第二行格式是比如
i=100,只需要调整i_extract_rule的逻辑即可,比如改成lambda line: int(line.strip().split("=")[-1])。
Shell单行命令方案(适合小数据量快速处理)
如果不想写Python,也可以用awk组合实现:
# 先提取所有xyz文件的i值存到临时文件 for f in *.xyz; do sed -n '2p' $f | awk '{print int($NF)}' >> i_list.tmp; done # 匹配长数据文件的Step列(假设Step是第一列),输出前三列 awk 'NR==FNR{i_set[$1]=1; next} i_set[$1]==1 {print $1,$2,$3}' i_list.tmp long_data.txt > matched_result.txt # 清理临时文件 rm i_list.tmp
两种方案都完全基于i值的精准匹配,哪怕长数据有缺行、xyz文件的保存间隔不是严格固定也不会出现匹配错位的问题。
内容的提问来源于stack exchange,提问作者Ant
相关产品推荐
相关产品推荐

