使用 awk 查找可变长度的正则表达式并根据找到的长度编辑以下行
Use awk to find regex of variable length and edit following lines based on length found
我正在尝试用 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 }'
但我不知道如何在两行后删除相同数量的字符。
我很没有经验,才开始学习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 包含模式
这可能有效,但由于您的示例输入不包含任何与正则表达式匹配的行,并且您没有提供任何预期的输出,当然它未经测试:
NR%4 == 2 { match([=10=],/AGATCGGAAG[ATGC]{0,24}$/) }
RSTART && (NR%4 ~ /^[02]$/) { [=10=] = substr([=10=],1,RSTART-1) }
{ print }
Perl 解决方案:
#! /usr/bin/perl
use warnings;
use strict;
my $length;
while (<>) { # Read line by line.
if (2 == $. % 4) {
$length = length if s/(TAGAGA[ACTG]{0,7})$//;
} elsif (0 == $. % 4 && $length) { # We should shorten this line.
s/.{$length}$//;
undef $length; # Done.
}
print;
}
有点长,但应该可以:
awk '
BEGIN {
n=-1
pat="AGATCGGAAG[ATGC]{0,24}$"
}
NR%4==2 && [=10=] ~ pat {
match([=10=], pat);
gsub(pat, "");
n=NR+2;
}
NR==n {
print substr([=10=],1,RSTART-1) substr([=10=],RSTART+RLENGTH)
next
}
{ print }
'
我正在尝试用 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 }'
但我不知道如何在两行后删除相同数量的字符。 我很没有经验,才开始学习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 包含模式
这可能有效,但由于您的示例输入不包含任何与正则表达式匹配的行,并且您没有提供任何预期的输出,当然它未经测试:
NR%4 == 2 { match([=10=],/AGATCGGAAG[ATGC]{0,24}$/) }
RSTART && (NR%4 ~ /^[02]$/) { [=10=] = substr([=10=],1,RSTART-1) }
{ print }
Perl 解决方案:
#! /usr/bin/perl
use warnings;
use strict;
my $length;
while (<>) { # Read line by line.
if (2 == $. % 4) {
$length = length if s/(TAGAGA[ACTG]{0,7})$//;
} elsif (0 == $. % 4 && $length) { # We should shorten this line.
s/.{$length}$//;
undef $length; # Done.
}
print;
}
有点长,但应该可以:
awk '
BEGIN {
n=-1
pat="AGATCGGAAG[ATGC]{0,24}$"
}
NR%4==2 && [=10=] ~ pat {
match([=10=], pat);
gsub(pat, "");
n=NR+2;
}
NR==n {
print substr([=10=],1,RSTART-1) substr([=10=],RSTART+RLENGTH)
next
}
{ print }
'