Expertos:我想根据字符串(部分和精确)提取字段。在某些行中,这些字段被移动一列或两列,所以我无法指定列(这是我的知识范围)。我还需要提取第 1、2、4 和 5 个字段,但这些字段不会逐行变化,所以我可以自己完成。
具体来说,我想提取具有部分字符串“的字段DP4=" 以及具有匹配字符串的字段,如 "缓和”加上左侧和右侧的字段:
输入:
NW_006532014.1 603822 . T C 222.0 . DP=103 ADF=30,22 ADR=13,16 AD=43,38 VDB=0.0570121 SGB=-0.693143 RPB=0.810487 MQB=0.570226 MQSB=0.033126 BQB=0.964281 MQ0F=0 ICB=1 HOB=0.5 AC=1 AN=2 DP4=30,13,22,16 MQ=35 ANN=C missense_variant MODERATE ABCB6 ABCB6 transcript XM_007419806.2
NW_006532015.1 1015800 . AAA AAACAA 228.0 . INDEL IDV=106 IMF=0.905983 DP=117 ADF=6,50 ADR=19,42 AD=25,92 VDB=0.22041 SGB=-0.693147 MQSB=0.182586 MQ0F=0 AC=2 AN=2 DP4=6,19,50,42 MQ=36 ANN=AAACAA disruptive_inframe_insertion MODERATE CEP131 CEP131 transcriptXM_025166060.1 protein_coding 11/27
NW_006532017.1 910856 . C G 78.0 . DP=118 ADF=50,14 ADR=25,2 AD=75,16 VDB=0.954018 SGB=-0.689466 RPB=0.939107 MQB=0.0031569 MQSB=0.280595 BQB=0.0859367 MQ0F=0 ICB=1 HOB=0.5 AC=1 AN=2 DP4=50,25,14,2 MQ=44 ANN=G missense_variant MODERATE HPS1 HPS1 transcript XM_025169525.1
NW_006532033.1 475415 . T C 222.0 . DP=123 ADF=18,36 ADR=18,15 AD=36,51 VDB=0.984451 SGB=-0.693147 RPB=0.428811 MQB=1.68713e-05 MQSB=0.565818 BQB=0.837943 MQ0F=0 ICB=1 HOB=0.5 AC=1 AN=2 DP4=18,18,36,15 MQ=41 ANN=C missense_variant MODERATE PTCH2 PTCH2 transcript XM_025164053.1
NW_006532040.1 586236 . G C 29.9689 . DP=106 ADF=40,9 ADR=25,1 AD=65,10 VDB=0.731987 SGB=-0.670168 RPB=0.945403 MQB=0.00509228 MQSB=0.210814 BQB=0.365756 MQ0F=0 ICB=1 HOB=0.5 AC=1 AN=2 DP4=40,25,9,1 MQ=46 ANN=C missense_variant MODERATE OMG OMG transcript XM_007420376.3
NW_006532040.1 674528 . T C 221.0 . DP=128 ADF=39,15 ADR=19,9 AD=58,24 VDB=0.253732 SGB=-0.692831 RPB=0.952839 MQB=1.09944e-10 MQSB=0.755937 BQB=0.749586 MQ0F=0 ICB=1 HOB=0.5 AC=1 AN=2 DP4=39,19,15,9 MQ=48 ANN=C missense_variant MODERATE NF1 NF1 transcript XM_007420379.3
所需的输出(制表符分隔):
DP4=30,13,22,16 missense_variant MODERATE ABCB6
DP4=6,19,50,42 disruptive_inframe_insertion MODERATE CEP131
DP4=50,25,14,2 missense_variant MODERATE HPS1
DP4=18,18,36,15 missense_variant MODERATE PTCH2
DP4=40,25,9,1 missense_variant MODERATE OMG
DP4=39,19,15,9 missense_variant MODERATE NF1
谢谢!
答案1
使用 GNU awk 作为第三个参数 to match()
、\<
字边界和\s/\S
简写:
$ awk -v OFS='\t' 'match($0,/(\<DP4=\S+).*\s(\S+\tMODERATE\t\S+)/,a){print a[1], a[2]}' file
DP4=30,13,22,16 missense_variant MODERATE ABCB6
答案2
awk 'BEGIN{ OFS="\t" } {
nrf=split($0, tmp); s1=s2=0;
for(i=1; i<=nrf; i++){
printf "%s", (tmp[i] ~/DP4=/ &&++s1? (s2?OFS:"") tmp[i]:
(tmp[i]=="MODERATE" &&++s2? (s1?OFS:"") tmp[i-1] OFS tmp[i] OFS tmp[i+1]:"") );
}; print "";
}' infile
我们用了split() 函数每次将当前处理行拆分到一个名为的临时数组tmp在默认 FS 上(空格,即制表符/空格);这nrf
只是我使用的一个临时变量,它保存 split() 函数分割的字段数。
然后我们对这些字段使用 for-look,并检查当前读取的字段是否tmp[i]
满足您期望的条件,如果是,则打印,否则我们将检查下一个条件,如果看到了,则将前一个字段打印到其中tmp[i-1]
然后是当前字段本身,tmp[i]
然后是它的右侧下一个字段tmp[i+1]
,否则我们打印空字符串""
。
临时变量s1
和s2
用于控制第一个和第二个打印条件操作之间的字段分隔符,因此如果在下一个字段之前找到一个字段,则应提前打印 OFS before。