使用awk查找可变长度的正则表达式,并根据找到的长度编辑以下行

时间:2015-06-02 13:40:00

标签: linux bash shell awk fastq

我正在尝试使用awk编辑fastq文件。

@someheader example fastq file
TGTACTTAGAGAAGCGC
+
BDDADHHIHHHIICHIG
@nextheader
CCGTAACCTGGGCAGTG
+
DDDDDHIIIIIIIIIII

我想要实现的目标是:

  • 寻找以下正则表达式:/ AGATCGGAAG [ATGC] {0,24} $ / - 如果可能的话只能在其实际可能找到的行中(例如,行2,6,10,x + 2%4 = 0基本上)
  • 如果找到,请删除匹配
  • 然后在当前行
  • 之后的第2行删除相同数量的字符

到目前为止,基于正则表达式编辑一行对我来说没有问题,我用过:

awk '{ gsub(/AGATCGGAAG[ATGC]{0,24}$/, ""); print RLENGTH }'

但我不知道如何在2行后删除相同数量的字符。 我很缺乏经验,只是开始学习awk,所以欢迎任何帮助。

问候

编辑:以下是包含上述模式的示例

@HWI-ST558:329:H3K2GBCXX:1:1101:5408:2985 1:N:0:ATCACG
CCTCCCGGTCGGTGCTGAGAGAGACTGGGCTCTCTGGAACTCCACCACCGAGATCGGAAGAG
+
HHHIIIIHDHIIIHIIGHHHIHFHHCHHIE?GHHGHF?GECFEEHFHHHCHDHHHFEEHHHH

这应该是输出:

@HWI-ST558:329:H3K2GBCXX:1:1101:5408:2985 1:N:0:ATCACG
CCTCCCGGTCGGTGCTGAGAGAGACTGGGCTCTCTGGAACTCCACCACCG
+
HHHIIIIHDHIIIHIIGHHHIHFHHCHHIE?GHHGHF?GECFEEHFHHHC

该文件包含4000万条这样的条目,其中〜250k包含模式

3 个答案:

答案 0 :(得分:1)

这可能会有效,但由于您的示例输入不包含与正则表达式匹配的任何行,并且您没有提供任何预期的输出,当然它未经测试:

NR%4 == 2 { match($0,/AGATCGGAAG[ATGC]{0,24}$/) }
RSTART && (NR%4 ~ /^[02]$/) { $0 = substr($0,1,RSTART-1) }
{ print }

答案 1 :(得分:0)

Perl解决方案:

#! /usr/bin/perl
use warnings;
use strict;

my $length;
while (<>) {                            # Read line by line.
    if (2 == $. % 4) {
        $length = length $1 if s/(TAGAGA[ACTG]{0,7})$//;
    } elsif (0 == $. % 4 && $length) {  # We should shorten this line.
        s/.{$length}$//;
        undef $length;                  # Done.
    }
    print;
}

答案 2 :(得分:0)

它有点长,但它应该有效:

awk '
    BEGIN {
        n=-1
        pat="AGATCGGAAG[ATGC]{0,24}$"
    }
    NR%4==2 && $0 ~ pat {
        match($0, pat);
        gsub(pat, "");
        n=NR+2;
    }
    NR==n {
        print substr($0,1,RSTART-1) substr($0,RSTART+RLENGTH)
        next
    }
    { print }

'