AWK脚本重复打印同一行求助:筛选含<200值的行列
解决大表格筛选问题:保留含数值<200的列与行,避免重复打印
问题分析
你当前的核心问题是原awk脚本会因同一行存在多个<200的单元格而重复打印该行,同时需要完成:保留表头、移除所有值>200的列和行、不转置表格的需求。
原脚本问题根源:for循环中每匹配一个<200的单元格就执行print,导致同一行多次输出。
解决方案
使用awk两次遍历表格:第一次标记需要保留的列,第二次按标记输出符合条件的行(仅打印一次)。
完整脚本
创建脚本文件filter_table.awk:
# 第一次遍历:标记需保留的列(前2列强制保留,后续列只要有任意行值<200则保留) NR == FNR { if (NR == 1) { for (i = 1; i <= 2; i++) keep[i] = 1 } else if (NR > 2) { # 跳过表头后的分隔线行 for (i = 3; i <= NF; i++) { if ($i + 0 < 200) { # +0确保按数值比较,避免字符串干扰 keep[i] = 1 } } } next } # 第二次遍历:输出符合条件的行和列 { out_str = "" has_valid_val = 0 for (i = 1; i <= NF; i++) { if (keep[i]) { # 拼接输出内容 out_str = out_str (out_str == "" ? "" : OFS) $i # 检查数据行是否存在有效数值 if (NR > 2 && $i + 0 < 200) { has_valid_val = 1 } } } # 输出表头、分隔线或有效数据行 if (NR == 1 || NR == 2) { print out_str } else if (has_valid_val) { print out_str } }
运行命令
awk -f filter_table.awk table.txt
脚本说明
- 第一次遍历:
- 表头行(第1行):强制保留前2列(Gene、targ_bp)
- 跳过第2行的分隔线,遍历所有数据行,标记所有存在<200数值的列
- 第二次遍历:
- 仅拼接并输出标记为保留的列
- 表头和分隔线直接输出
- 数据行仅当存在至少一个<200的数值时才输出,且仅打印一次
效果验证
针对你的示例输入,运行后会输出:
| Gene | targ_bp | s_1 | s_2 | |------|---------|-----|-----| | GNB1 | 217 | 53 | 102 | | GNB1 | 202 | 1112| 96 |
完全符合期望:移除了无有效数值的s_3列,跳过了全为>200的第三行数据,且无重复打印。
内容的提问来源于stack exchange,提问作者Heidi Ottesen
相关产品推荐
相关产品推荐

