【问题标题】:AWK - Printing a specific patternAWK - 打印特定图案
【发布时间】:2015-03-25 10:02:05
【问题描述】:

我的文件看起来像这样

gene_id_100100  sp|Q53IZ1|ASDP_PSESP    35.81   148 90  2   13  158 6   150 6e-27    109    158 531
gene_id_100600  sp|Q49W80|Y1834_STAS1   31.31   99  63  2   1   95  279 376 7e-07   50.1    113 402
gene_id_100     sp|A7TSV7|PAN1_VANPO    36.36   44  24  1   41  80  879 922 1.9 32.3    154 1492
gene_id_10100   sp|P37348|YECE_ECOLI    32.77   177 104 6   3   172 2   170 2e-13   71.2    248 272
gene_id_101100  sp|B0U4U5|SURE_XYLFM    29.11   79  41  3   70  148 143 206 0.14    35.8    175 262
gene_id_101600  sp|Q5AWD4|BGLM_EMENI    35.90   39  25  0   21  59  506 544 4.9 30.4    129 772
gene_id_102100  sp|P20374|COX1_APILI    38.89   36  22  0   3   38  353 388 0.54    32.0    92  521
gene_id_102600  sp|Q46127|SYW_CLOLO     79.12   91  19  0   1   91  1   91  5e-44    150    92  341
gene_id_103100  sp|Q9UJX6|ANC2_HUMAN    53.57   28  13  0   11  38  608 635 2.1 28.9    42  822
gene_id_103600  sp|C1DA02|SYL_LARHH     35.59   59  30  2   88  138 382 440 4.6 30.8    140 866
gene_id_104100  sp|B8DHP2|PROB_LISMH    25.88   85  50  2   37  110 27  109 0.81    32.3    127 276
gene_id_105100  sp|A1ALU1|RL3_PELPD     31.88   69  42  2   14  77  42  110 2.2 31.6    166 209
gene_id_105600  sp|P59696|T200_SALTY    64.00   125 45  0   5   129 3   127 9e-58    182    129 152
gene_id_10600   sp|G3XDA3|CTPH_PSEAE    28.38   74  48  1   4   77  364 432 0.56    31.6    81  568
gene_id_106100  sp|P94369|YXLA_BACSU    35.00   100 56  3   25  120 270 364 4e-08   53.9    120 457
gene_id_106600  sp|P34706|SDC3_CAEEL    60.00   20  8   0   18  37  1027    1046    2.3 32.7    191 2150

现在,我需要提取基因 ID,它是 || 之间的那个。在第二列。换句话说,我需要一个如下所示的输出:

Q53IZ1  
Q49W80  
A7TSV7  
P37348  
B0U4U5  
Q5AWD4  
P20374  
Q46127  
Q9UJX6  
C1DA02  
B8DHP2  
A1ALU1  
P59696  
G3XDA3  
P94369
P34706

我一直在尝试使用以下命令:

awk '{for(i=1;i<=NF;++i){ if($i==/[A-Z][A-Z0-9][A-Z0-9][A-Z0-9][A-Z0-9][A-Z0-9]/){print $i} } }'

但它似乎不起作用。

【问题讨论】:

    标签: regex awk pattern-matching


    【解决方案1】:

    模式匹配并不是真正需要的。我建议

    awk -F\| '{print $2}' filename
    

    这会将行拆分为|-delimited 字段并打印其中的第二个。

    或者,

    cut -d\| -f 2 filename
    

    达到同样的效果。

    【讨论】:

    • 哇,效果很好!而且它看起来也很简单,不像我试图使用的那段代码哈哈。非常感谢您的帮助,限制解除后,我会在 9 分钟内接受您的答复。你是救生员。
    • 不过,如果你有时间,你能告诉我为什么我使用的命令不起作用吗?
    • 嗯,从哪里开始。嗯,首先,就 awk 而言,| 之间的内容不是一个字段,因为它的默认字段分隔符是一系列空格。第一行的$2 在您的代码中是sp|Q53IZ1|ASDP_PSESP。其次,您使用比较运算符== 而不是正则表达式匹配运算符~,这对正则表达式没有多大意义。我不认为它的作用是定义的。 gawk 似乎进行数字转换(?)。如果您使用了~,那么您将打印包含匹配项的字段,而不是匹配项本身。
    • 因此您必须提取匹配项。看起来像这样:awk '{ for(i = 1; i &lt;= NF; ++i) { pos = match($i, /[A-Z][A-Z0-9]{5}/); if(pos != 0) { print substr($i, pos, RLENGTH); } } } '。请注意,正则表达式匹配不限于这种方式的第二列;如果有,比如说,gene_id_A12345A12345 将出现在结果列表中。我不确定我是否理解您为什么觉得有必要遍历所有字段,老实说,因为您似乎只对 $2 感兴趣。
    • 我在awk '{ p = match($2, /\|.*\|/); if(p != 0) { print substr($2, p + 1, RLENGTH - 2); } }' 中看到了一些道理,可以稍微转一下这个想法。
    猜你喜欢
    • 2015-04-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-03
    • 2018-03-25
    • 1970-01-01
    • 2021-03-23
    相关资源
    最近更新 更多