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

寻求基于双条件的Awk脚本:利用file1过滤file2列数据

完整Awk解决方案

awk '
BEGIN { FS = OFS = " " }
FILENAME == "file1.txt" {
    descr[$1] = $2
    next
}
NR == 1 {
    for (i=1; i<=NF; i++) headers[i] = $i
    print
    next
}
{
    for (i = 1; i <= NF; i++) {
        col_val = $i
        if (col_val == "n/n") {
            res[i] = "n/n"
            continue
        }
        # 拆分冒号获取总读数(第三个字段)
        split(col_val, parts, ":")
        total = parts[3] + 0
        # 获取file1中对应列的阈值
        threshold = descr[headers[i]] + 0
        # 条件1:总读数在阈值的1/2到2倍之间
        cond1 = (total >= threshold/2 && total <= threshold*2)
        
        # 拆分逗号获取两个子读数
        split(parts[2], nums, ",")
        num1 = nums[1] + 0
        sum = num1 + (nums[2] + 0)
        # 计算比例,避免除以0
        ratio = sum == 0 ? 0 : num1 / sum
        # 条件2:比例不在0.1-0.25或0.75-0.9区间内
        cond2 = !( (ratio >= 0.1 && ratio <= 0.25) || (ratio >= 0.75 && ratio <= 0.9) )
        
        # 两个条件都满足才保留原值,否则替换为n/n
        res[i] = (cond1 && cond2) ? col_val : "n/n"
    }
    # 拼接结果行并输出
    for (i = 1; i <= NF; i++) {
        printf "%s%s", res[i], (i == NF ? "\n" : OFS)
    }
}
' file1.txt file2.txt

代码解释

  1. 初始化与file1处理

    • BEGIN { FS = OFS = " " }:设置输入输出分隔符为空格,适配两个文件的格式;如果你的实际文件用制表符分隔,只需将此处改为FS = OFS = "\t"。
    • 读取file1.txt时,将t1/t2/t3作为键,对应数值存入数组descr,完成后跳过后续逻辑。
  2. 表头处理

    • 读取file2.txt的第一行(表头),将每个列名存入headers数组,用于后续匹配descr中的阈值,然后直接输出表头。
  3. 数据行处理

    • 遍历每一行的每个字段:
      • 若字段本身是n/n,直接保留为结果。
      • 用split按冒号拆分字段,提取第三个值(总读数),判断是否在对应阈值的[值/2, 值*2]区间内(条件1)。
      • 拆分逗号分隔的子读数,计算第一个值与总和的比例,判断是否不在0.1-0.25或0.75-0.9区间内(条件2)。
      • 仅当两个条件同时满足时保留原字段值,否则替换为n/n。
    • 最后将结果数组拼接成一行输出。

验证结果

运行上述命令后,输出与期望完全一致:

t1 t2 t3
A/A:10,0:10 n/n n/n
A/B:10,8:18 n/n n/n
n/n n/n n/n

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 00:15:17