如何用awk筛选第二列以chr1_或chr7_开头的大文件数据?
筛选压缩文件中第二列以chr1_或chr7_开头的行
问题背景
有一个包含7列、1.92亿行的压缩文件file.txt.gz,需要筛选出第二列以chr1_或chr7_开头的行。第二列格式为chrnumber_number_letter_letter_b38,仅需匹配前缀严格为chr1_或chr7_的行。
输入示例(file.txt.gz前几行)
gene_id variant_id tss_distance ma_samples ma_count maf pval_nominal slope slope_se ENSG00000227232.5 chr1_13550_G_A_b38 -16003 16 16 0.0132231 0.329834 0.188778 0.193552 ENSG00000227232.5 chr1_14671_G_C_b38 -14882 12 12 0.00991736 0.618791 0.110828 0.222611 ENSG00000227232.5 chr2_14677_G_A_b38 -14876 60 60 0.0495868 0.378305 -0.090737 0.102905 ENSG00000227232.5 chr3_16841_G_T_b38 -12712 46 46 0.0380165 0.100419 -0.191008 0.116067 ENSG00000227232.5 chrX_16856_A_G_b38 -12697 10 10 0.00826446 0.708684 -0.0901965 0.241282 ENSG00000227232.5 chrX_17005_A_G_b38 -12548 18 18 0.014876 0.153674 -0.257458 0.180205 ENSG00000227232.5 chr4_17005_A_G_b38 -12548 18 18 0.014876 0.153674 -0.257458 0.180205 ENSG00000227232.5 chr7_17005_A_G_b38 -12548 18 18 0.014876 0.153674 -0.257458 0.180205
期望输出示例
gene_id variant_id tss_distance ma_samples ma_count maf pval_nominal slope slope_se ENSG00000227232.5 chr1_13550_G_A_b38 -16003 16 16 0.0132231 0.329834 0.188778 0.193552 ENSG00000227232.5 chr1_14671_G_C_b38 -14882 12 12 0.00991736 0.618791 0.110828 0.222611 ENSG00000227232.5 chr7_17005_A_G_b38 -12548 18 18 0.014876 0.153674 -0.257458 0.180205
原命令问题分析
之前使用的命令:
gunzip -c file.txt.gz | awk '$2 ~ /^chr1/' > output.txt
存在两个问题:
- 正则
/^chr1/仅匹配以chr1开头的字符串,会错误包含chr10_、chr19_等行,因为没有限定chr1后必须紧跟下划线_。 - 未添加
chr7_的筛选条件。
正确解决方案
方案1:合并正则匹配
使用括号分组匹配1或7,并明确限定后面的下划线,同时保留表头(NR==1表示第一行直接输出):
gunzip -c file.txt.gz | awk 'NR==1 || $2 ~ /^chr(1|7)_/' > output.txt
方案2:多条件或运算
如果觉得分组正则不够直观,也可以拆分为两个独立的正则条件:
gunzip -c file.txt.gz | awk 'NR==1 || $2 ~ /^chr1_/ || $2 ~ /^chr7_/' > output.txt
说明
NR==1:确保表头行被保留,因为表头的第二列是variant_id,不会匹配正则条件。/^chr(1|7)_/:精确匹配以chr1_或chr7_开头的第二列,避免误匹配chr10_等不符合要求的行。
内容的提问来源于stack exchange,提问作者HKJ3
相关产品推荐
相关产品推荐

