You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

AWK多列条件遍历 满足条件输出首列值的实现方法

TSV按列归集筛选AWK方案

问题说明

待处理数据为制表符分隔(TSV)格式,实际数据量约20000行,示例数据如下:

Names	USA	EU	FR
Jim	3	12	5
John	8	4	7
Jane	12	35	3
Sue	6	3	9

原始数据示例

处理规则

从第2列开始遍历所有列,收集单元格数值大于5对应的行首列(名称列)值,最终输出制表符分隔结果,要求:

  • 首行为原数据第2列及之后所有列的表头
  • 每列下方按顺序排列对应列满足数值>5条件的名称
    预期输出:
USA	EU	FR
John	Jim	John
Jane	Jane	Sue
Sue

预期结果示例

原有脚本问题

之前编写的脚本:

awk -F"\t" '{ 
        for(i=2; i<=NF; i++) {
            if($i > 5){
                print $1 
            } 
        }
    }' file > results

存在两个核心问题:

  1. 遍历到符合条件的值就直接打印名称,没有按列做归集存储,所有结果只能输出到单列,无法对齐成多列格式
  2. 未单独处理首行表头,后续尝试添加的print FNR == i {print $1} "\n"不符合awk语法规则(不支持将条件代码块直接嵌套在print语句内),因此触发语法报错:
awk: cmd. line:4:                 print FNR == i {print $1} "\n"
awk: cmd. line:4:                                ^ syntax error
awk: cmd. line:8:     }
awk: cmd. line:8:     ^ syntax error

正确实现脚本

BEGIN {
    FS = "\t"
    OFS = "\t"
}
NR == 1 {
    col_total = NF - 1
    for (i=2; i<=NF; i++) {
        idx = i - 1
        header[idx] = $i
        col_len[idx] = 0
    }
    next
}
{
    for (i=2; i<=NF; i++) {
        if ($i + 0 > 5) {
            idx = i - 1
            col_len[idx]++
            res[idx, col_len[idx]] = $1
            max_row = (col_len[idx] > max_row ? col_len[idx] : max_row)
        }
    }
}
END {
    # 打印表头
    for (i=1; i<=col_total; i++) {
        printf "%s%s", header[i], (i==col_total ? "\n" : OFS)
    }
    # 逐行打印归集结果
    for (r=1; r<=max_row; r++) {
        for (i=1; i<=col_total; i++) {
            val = (r <= col_len[i] ? res[i, r] : "")
            printf "%s%s", val, (i==col_total ? "\n" : OFS)
        }
    }
}

使用方法

将脚本保存为filter.awk,执行命令:

awk -f filter.awk input.tsv > output.tsv

脚本单次遍历文件即可完成所有归集操作,处理20000行数据无性能压力,内存占用仅和符合条件的结果总量相关。


内容的提问来源于stack exchange,提问作者Haloor

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 15:24:26