基于第二文件表头提取第一文件指定列(Matlab/R实现)
从制表符分隔表中提取指定列的实用方案
我来分享几个高效的方法,帮你从大型制表符分隔表Data.txt里,提取出List.txt指定表头对应的所有列,处理大文件也完全hold住。
先明确需求场景
我们手头有两个文件:
Data.txt:首行是表头的大型制表符分隔文本表List.txt:包含Data.txt表头的子集,我们要提取对应这些表头的列
举个实际例子:
Data.txt内容:
head0 head1 head2 head3 head4 1 25 1364 22 13 2 10 215 1 22List.txt内容:
head0 head4期望输出:
head0 head4 1 13 2 22
方法一:用awk命令(最推荐,灵活高效)
awk是处理这类文本列操作的神器,不仅能准确提取,还能严格遵循List.txt里的表头顺序,对大文件也很友好:
awk ' # 先读List.txt,把要保留的表头存进数组 NR==FNR { cols[$1]; next } # 处理Data.txt的表头行,记录需要保留的列的位置和顺序 FNR==1 { for (i=1; i<=NF; i++) { if ($i in cols) { keep[i] = 1 order[++k] = i # 按List.txt的顺序保存列索引 } } } # 处理每一行,按记录的顺序输出列 { for (i=1; i<=k; i++) { printf "%s%s", $(order[i]), (i<k ? OFS : ORS) } } ' List.txt Data.txt
额外优化:严格处理制表符分隔
如果你的文件是严格用制表符分隔(避免空格干扰),可以指定分隔符参数,确保准确性:
awk -F'\t' -v OFS='\t' ' NR==FNR { cols[$1]; next } FNR==1 { for (i=1; i<=NF; i++) { if ($i in cols) { keep[i] = 1; order[++k] = i } } } { for (i=1; i<=k; i++) { printf "%s%s", $(order[i]), (i<k?OFS:ORS) } } ' List.txt Data.txt
方法二:用cut命令(适合简单场景)
如果不需要严格遵循List.txt的顺序,也可以先获取列号再用cut提取,步骤如下:
# 第一步:获取需要保留的列的编号 cols=$(head -1 Data.txt | tr '\t' '\n' | grep -n -f List.txt | cut -d: -f1 | paste -sd,) # 第二步:提取对应列 cut -f$cols Data.txt
⚠️ 注意:这个方法输出的列顺序会和Data.txt表头的顺序一致,而不是List.txt里的顺序,所以如果要求顺序匹配的话,还是优先用awk方法。
内容的提问来源于stack exchange,提问作者user6985
相关产品推荐
相关产品推荐

