使用awk筛选TSV文件第二列唯一值对应第五列失败,求排查
AWK命令未过滤连续重复行的问题排查与解决
问题背景
有一份TSV格式的文件,部分内容如下:
chr1 28932 29543 chr1 29159 29422 RNAPOLII_T1_pos_1_q05_peak_1 114 . 5.55679 14.5827 11.4511 119 chr1 199425 200055 . -1 -1 . . . . . . . chr1 206917 207235 . -1 -1 . . . . . . . chr1 629342 630035 chr1 629392 629981 RNAPOLII_T1_pos_1_q05_peak_2 89 . 1.53473 11.9814 8.95881 434 chr1 630824 631475 chr1 630904 631286 RNAPOLII_T1_pos_1_q05_peak_3 110 . 1.66136 14.1185 11.0065 34 chr1 631947 632282 . -1 -1 . . . . . . . chr1 632546 632864 chr1 632596 632814 RNAPOLII_T1_pos_1_q05_peak_4 53 . 1.45791 8.17161 5.34813 45 chr1 633792 634430 chr1 634016 634206 RNAPOLII_T1_pos_1_q05_peak_5 42 . 1.40136 6.99814 4.24691 25 chr1 634453 634840 chr1 634503 634790 RNAPOLII_T1_pos_1_q05_peak_6 68 . 1.68267 9.80195 6.88384 32 chr1 778082 779111 chr1 778407 778997 RNAPOLII_T1_pos_1_q05_peak_7 290 . 8.3336 32.7328 29.0707 207 chr1 827049 827851 chr1 827150 827773 RNAPOLII_T1_pos_1_q05_peak_8 43 . 3.42454 7.13586 4.37707 251 chr1 941573 941926 chr1 941623 941876 RNAPOLII_T1_pos_1_q05_peak_9 48 . 3.83227 7.61827 4.82768 136 chr1 989375 989734 . -1 -1 . . . . . . . chr1 990673 991342 . -1 -1 . . . . . . . chr1 991736 992432 chr1 991990 992382 RNAPOLII_T1_pos_1_q05_peak_10 58 . 4.33261 8.71042 5.8516 205 chr1 992407 994252 chr1 992698 993311 RNAPOLII_T1_pos_1_q05_peak_11 62 . 3.89152 9.08737 6.20787 479 chr1 992407 994252 chr1 993534 994152 RNAPOLII_T1_pos_1_q05_peak_12 60 . 3.39559 8.88015 6.01409 170 chr1 994237 998788 chr1 994346 998738 RNAPOLII_T1_pos_1_q05_peak_13 633 . 13.9139 67.4929 63.32 2194 chr1 998775 1002233 chr1 998825 1002089 RNAPOLII_T1_pos_1_q05_peak_14 850 . 19.1217 89.4139 85.0549 1234 chr1 1004118 1004538 . -1 -1 . . . . . . . chr1 1005008 1006499 chr1 1005058 1005522 RNAPOLII_T1_pos_1_q05_peak_15 55 . 4.46653 8.38165 5.54531 345 chr1 1019994 1020390 . -1 -1 . . . . . . . chr1 1020344 1020662 . -1 -1 . . . . . . . chr1 1078905 1080785 chr1 1079111 1079300 RNAPOLII_T1_pos_1_q05_peak_16 48 . 3.07279 7.6091 4.82217 93 chr1 1078905 1080785 chr1 1079358 1079899 RNAPOLII_T1_pos_1_q05_peak_17 90 . 4.56426 12.0559 9.03203 158 chr1 1157419 1158008 chr1 1157469 1157958 RNAPOLII_T1_pos_1_q05_peak_18 113 . 5.84903 14.4751 11.3505 128 chr1 1216203 1216549 . -1 -1 . . . . . . . chr1 1216526 1216931 . -1 -1 . . . . . . . chr1 1231559 1232418 chr1 1231766 1232368 RNAPOLII_T1_pos_1_q05_peak_19 175 . 7.74351 20.8689 17.5159 180 chr1 1248702 1249624 . -1 -1 . . . . . . .
需求是筛选第二列值唯一的行对应的第五列数据,连续重复的第二列值只保留第一个对应的第五列(比如第16、17行第二列都是992407,只保留992698)。
编写的AWK命令如下:
awk 'BEGIN {$prev=-1} { if($2 != $prev){ print $5; $prev=$2 }}'
但执行后没有任何行被过滤,所有第五列数据都被输出了。
问题原因
你犯了一个AWK变量使用的基础错误:
- 在AWK中,
$prev表示字段变量,即引用编号为prev的列,而不是自定义的普通变量。 - 你在BEGIN块里给
$prev赋值,这实际上是试图修改第prev列的值,但此时prev未定义(默认值为0),所以这个赋值操作无效。 - 后续判断
$2 != $prev时,$prev始终指向不存在的第0列(实际为空值),所以$2永远不等于空值,导致所有行都被输出。
解决方法
把自定义变量的$符号去掉,使用普通变量来存储上一行的第二列值:
awk 'BEGIN {prev=-1} { if($2 != prev){ print $5; prev=$2 }}' your_file.tsv
解释
prev是普通自定义变量,用来存储上一行的第二列值。- BEGIN块初始化
prev为-1,确保第一行的$2必然不等于prev,会被正常输出。 - 每一行判断当前
$2是否和prev不同,不同则输出第五列,并更新prev为当前$2。
这样就能正确过滤掉连续重复的第二列对应的行,只保留每组连续重复行的第一个第五列值。
内容的提问来源于stack exchange,提问作者Whitehot
相关产品推荐
相关产品推荐

