MacOS下根据指定列名提取大文本文件对应列的简便方法咨询
解决方案
用系统自带的awk即可实现需求,单条命令就能完成,无需循环调用paste拼接,兼容Mac OS X自带的BSD awk,纯shell实现:
命令示例(针对TSV格式文件)
如果你的大文件是制表符分隔的TSV格式,直接使用以下命令:
awk 'BEGIN{FS=OFS="\t"} NR==FNR { # 预处理去掉列名行尾空白,避免匹配失败 gsub(/[[:space:]]*$/, "", $0) cols[++n] = $0 next } FNR == 1 { # 建立大文件列名到列索引的映射 for(i=1; i<=NF; i++) { col_idx[$i] = i } } { # 按列名文件的顺序输出匹配到的列 for(i=1; i<=n; i++) { if (col_idx[cols[i]]) { printf "%s%s", $(col_idx[cols[i]]), (i == n ? ORS : OFS) } } }' 待匹配列名文件.txt 大文本文件.tsv > 输出结果.tsv
适配空白分隔的文本文件
如果你的大文件是空格/任意空白分隔的,删除开头的BEGIN{FS=OFS="\t"}块即可,awk默认按任意空白分割列。
命令说明
- 先读取待匹配列名文件,按输入顺序存储列名,同时自动去掉列名行尾的多余空白,避免匹配失败
- 读取大文件的首行,建立列名到对应列序号的映射表
- 遍历大文件的每一行,按列名文件的顺序输出存在的列,不存在的列自动忽略,完全符合要求的输出顺序
- 全程只需要读取两个文件各一次,性能远高于循环遍历+paste的方案,大文件场景下效率优势更明显
内容的提问来源于stack exchange,提问作者user36196
相关产品推荐
相关产品推荐

