使用awk过滤行

2022-06-02 15:50:00 浏览数 (1)

被过滤的数据

代码语言:javascript复制
MarkerName  Allele1 Allele2 Freq1   FreqSE  P-value Chr Pos
rs2326918   a        g      8510    0001    5255    6   130881784
rs2439906   c        g      0316    0039    8997    10  6870306
rs10760160  a        c      5289    0191    8107    9   123043147
rs977590    a        g      9354    0023    8757    7   34415290
rs17278013  t        g      7498    0067    3595    14  24783304
rs7852050   a        g      8814    0006    7671    9   9151167
rs7323548   a        g      0432    0032    4555    13  112320879
rs12364336  a        g      8720    0015    4542    11  99515186
rs12562373  a        g      7548    0020    6151    1   164634379

我们想要做的是Chr当它等于 6 时从(第 7 列)获取行,并且Pos当值在 11000000 和 25000000 之间时从(第 8 列)获取行。

例如,我们知道我们的数据中有 8 个由制表符分隔的列,但是如果你不知道有多少列,你可以通过一些awk找到它:

代码语言:javascript复制
> awk "{print NF}" < rumenz.txt | uniq

8

NF是一个 AWK 内置变量,它代表_字段数_。我们通过管道将其传递给,uniq因为默认行为将打印每行的列数,并且由于每行具有相同的列数,因此uniq会将其减少为一个数字。

打印字段和搜索

我们还可以使用 awk来选择和打印文件的一部分。让我们现在这样做。

代码语言:javascript复制
> awk '{print $1 $2}' rumenz.txt
代码语言:javascript复制
rs11058339t
rs7338610t
rs882601t
rs13290449t
rs2941056a
rs10444526a
rs12190167a
rs1125337a
rs7911101a
rs13053206c
rs697690t
rs12447687t
rs2402752t
rs12042911a
...

请注意,输出没有格式。有很多方法可以在 awk中格式化和构建输出。查看awk用户指南上的打印部分以获取更多信息。

现在我们已经选择了几列来打印出来,让我们使用awk 来搜索一个特定的东西——我们知道数据集中存在的一个数字。请注意,如果你指定要打印哪些字段,awk将默认打印与搜索匹配的整行。

代码语言:javascript复制
> awk '/2410626/' rumenz.txt
代码语言:javascript复制
rs4853805   a   t   2107  0029  4229  2   2410626

我们可以匹配一个字符串模式或正则表达式,而不是匹配一个唯一的数字。在这种情况下,awk 将返回与模式匹配的每一行。在我们上面的例子中,这个数字在数据文件中出现一次,但我们可以使用正则表达式或范围模式来代替。有关在 awk 中查找模式的更多信息,请查看awk 指南的模式、操作和变量部分。

根据字段值过滤行

现在我们知道如何访问字段(列)并在我们的文档中查找模式,但是我们如何控制要搜索的内容和位置?我们最初的问题要求我们查看该Chr字段以仅获取值为 6 的行。然后我们希望查看该Pos字段以获取这些值介于 11000000 和 25000000 之间的行。要在 awk 中执行此操作,我们需要使用在if同一个条件表达式一起控制语句。

代码语言:javascript复制
> awk '{ if ($7 == 6) { print } }' rumenz1-txt | head
代码语言:javascript复制
rs2326918   a   g   8510  0001  5255  6   130881784
rs16877977  a   g   1302  0048  05945 6   16494324
rs7763812   a   t   9815  0008  05328 6   104042808
rs222555    c   g   3720  0051  7756  6   95272331
rs9450727   t   c   6193  0106  08575 6   88293919
rs12200899  t   c   7683  0075  7118  6   66215503
rs990018    t   c   0201  0000  6292  6   68825590
rs1344178   a   c   6250  0016  7234  6   118804141
rs12529570  c   g   1987  0148  266   6   110283483
rs3130560   t   g   2706  0242  2365  6   31205432

上面,我们使用关键字if,然后使用条件表达式(7 == 6),基于7我们要测试的列变量。这里的表示我们正在处理一个变量,在这种情况下,awk 知道这7意味着我们数据集中的第 7 个字段。同样,

现在我们要在Pos列上测试条件的另一部分。这次我们将使用>=运算符来测试第 8 列中的值是否大于或等于 11000000。

代码语言:javascript复制
> awk '{ if($8 >= 11000000) { print }}' rumenz.txt | head
代码语言:javascript复制
MarkerName  Allele1 Allele2 Freq1   FreqSE  P-value Chr Pos
rs2326918         a   g     8510    0001    5255    6   130881784
rs10760160        a   c     5289    0191    8107    9   123043147
rs977590          a   g     9354    0023    8757    7   34415290
rs17278013        t   g     7498    0067    3595    14  24783304
rs7323548         a   g     0432    0032    4555    13  112320879
rs12364336        a   g     8720    0015    4542    11  99515186
rs12562373        a   g     7548    0020    6151    1   164634379
rs17706069        a   t     8055    0537    993     16  27095047
rs17035887        a   g     0588    0072    6673    2   46983448

到目前为止,我们已经确认我们可以使用ifawk 中的语句来返回满足条件的行。查看有关在 AWK 中使用控制语句的文档,了解更多使用条件进行决策的方法。

下一步是将这些条件表达式与第三个(小于 25000000)组合起来,一次性完成所有过滤。为此,我们需要在条件表达式中使用布尔运算符。让我们先对上面算出的两个条件表达式进行尝试。

代码语言:javascript复制
> awk  '{ if(($7 == 6) && ($8 >= 11000000)) { print } }' rumenz.txt | tail
代码语言:javascript复制
rs9320690   a   g   5342  0041  9136  6   119812605
rs483727    t   c   2512  0052  1624  6   81681348
rs754997    t   g   8192  0091  6605  6   133635869
rs2073214   t   c   1465  0007  1076  6   144123302
rs12195885  a   c   0224  0000  9662  6   23600679
rs6924121   t   c   6988  0031  4138  6   165249220
rs11961870  a   c   2470  0094  9404  6   143943842
rs9476984   c   g   0711  0014  9935  6   16036569
rs9382099   t   c   1443  0043  7554  6   52328752
rs2504065   a   g   4974  0009  3366  6   152136860

我们使用 boolean and && here(其他运算符是||for or!for not)来组合我们的两个条件语句。现在让我们将第二列$8条件 (<=25000000) 添加到 if 语句中。

代码语言:javascript复制
> awk '{ if(($7 == 6) && ($8 >= 11000000 && $8 <= 25000000)) { print } }' rumenz.txt
代码语言:javascript复制
rs16877977  a   g   1302  0048  05945 6   16494324
rs7767788   t   c   6144  0042  3234  6   14098813
rs12523811  a   c   5216  0055  2504  6   17941531
rs12199382  a   g   4045  0113  7856  6   22435109
rs9465281   c   g   0719  0105  1794  6   19326722
rs13196524  t   c   9426  0209  8672  6   22356754
rs12195885  a   c   0224  0000  9662  6   23600679
rs9476984   c   g   0711  0014  9935  6   16036569

相关文章

Shell三大利器之awk

linux之awk使用技巧

使用awk和正则表达式过滤文件中的文本或字符串

0 人点赞