Miller工具:如何基于列的最后一行值筛选列?
处理TSV文件按最后一行值筛选列的方法
针对你提到的两种筛选需求,这里用awk工具给出高效实现方案,适合处理上百列的大文件:
一、筛选最后一行值≥5的列
执行以下awk命令即可完成筛选:
BEGIN {FS=OFS="\t"} NR==1 {split($0, header); next} { split($0, row) for(i=1; i<=NF; i++) { data[i] = data[i] $i OFS } } END { split(data[1], last_row, OFS) # 输出符合条件的表头 for(i=1; i<=length(header); i++) { if(i==1 || last_row[i] >=5) { printf "%s%s", header[i], (i==length(header)?"\n":OFS) } } # 输出每一行对应列 for(i=1; i<=length(data); i++) { split(data[i], current_row, OFS) line = "" for(j=1; j<=length(header); j++) { if(j==1 || last_row[j] >=5) { line = line current_row[j] OFS } } sub(/\t$/, "", line) print line } }
使用方式
- 把上述代码保存为
filter_gt5.awk文件 - 在终端执行:
awk -f filter_gt5.awk your_tsv_file.tsv
二、筛选最后一行值≥Gi列对应值的列
这种需求需要先定位Gi列,再用其最后一行值作为阈值筛选,awk实现代码如下:
BEGIN {FS=OFS="\t"} NR==1 { split($0, header) # 找到Gi列的位置 for(i=1; i<=NF; i++) { if(header[i] == "Gi") gi_col = i } next } { split($0, row) for(i=1; i<=NF; i++) { data[i] = data[i] $i OFS } } END { split(data[gi_col], gi_data, OFS) threshold = gi_data[length(gi_data)-1] # 输出表头 for(i=1; i<=length(header); i++) { if(i==1 || i==gi_col) { printf "%s%s", header[i], OFS } else { split(data[i], col_data, OFS) last_val = col_data[length(col_data)-1] if(last_val >= threshold) { printf "%s%s", header[i], OFS } } } printf "\n" # 输出每一行数据 row_count = split(data[1], first_col, OFS) -1 for(r=1; r<=row_count; r++) { line = "" for(i=1; i<=length(header); i++) { if(i==1 || i==gi_col) { split(data[i], col_data, OFS) line = line col_data[r] OFS } else { split(data[i], col_data, OFS) last_val = col_data[length(col_data)-1] if(last_val >= threshold) { line = line col_data[r] OFS } } } sub(/\t$/, "", line) print line } }
使用方式
- 保存代码为
filter_gt_gi.awk - 终端执行:
awk -f filter_gt_gi.awk your_tsv_file.tsv
内容的提问来源于stack exchange,提问作者mikael-s
相关产品推荐
相关产品推荐

