Awk 提取某些行并快速操作它们

Awk 提取某些行并快速操作它们,awk,Awk,假设我有一个大文件(100G),如下所示(我简化了文件:1-实际上每行有更多字符,2-行不以数字开头) 行号%4==1的所有行的开头都有一个@。我想提取这些行及其下一行,并将@替换为“>”,然后将其输出到一个新文件中 输出将如下所示: >1ab 2sdasd >5fhd 6dhg >9aghf 10adfgh 以下是我的解决方案: awk 'NR%4==1 || NR%4==2 {gsub("@",">"); print}' infile > outfile a

假设我有一个大文件(100G),如下所示(我简化了文件:1-实际上每行有更多字符,2-行不以数字开头)

行号
%4==1
的所有行的开头都有一个
@
。我想提取这些行及其下一行,并将
@
替换为“>”,然后将其输出到一个新文件中

输出将如下所示:

>1ab
2sdasd
>5fhd
6dhg
>9aghf
10adfgh
以下是我的解决方案:

awk 'NR%4==1 || NR%4==2 {gsub("@",">"); print}' infile > outfile
awk '{ k=NR%4; if(k==1) print ">"substr($0,2); else if(k==2) print }' infile > outfile

有更快的方法吗?

Awk解决方案:

awk 'NR%4==1 || NR%4==2 {gsub("@",">"); print}' infile > outfile
awk '{ k=NR%4; if(k==1) print ">"substr($0,2); else if(k==2) print }' infile > outfile
  • k=NR%4
    -系数,每个记录只计算一次

outfile
内容(用于当前输入):


awk
,带/不带

getline
函数读取下一行并将脚本移动到 从下一个输入记录中,除了
$0
,它什么都没有;设置
NF
NR
FNR
RT


如果at字符仅作为“记录分隔符”出现,则可以使用
fgrep
tr
,例如:

fgrep——无组分隔符-A1'@'infle|tr@\>
这比您的awk解决方案快一个数量级

要坚持使用模数4,使用GNU sed的速度要快4倍,例如:

sed -n '1~4 { N; s/^@/>/p; }' infile
两种情况下的输出:

>1ab                                                                
2sdasd
>5fhd
6dhg
>9aghf
10adfgh

你不会比你写的更快找到任何东西。
gsub();它将交换所有
@
符号,而不仅仅是第一个符号。您可以使用
sub()
,它在第一次匹配后停止,这对性能有一点好处。您还可以在每对的两行上进行替换,但只需要在第一行上进行替换。解决这个问题可能会加快速度。但我想,差别不会那么大。谢谢!这比我的快,但由于@RomanPerekhrest解决方案快了.3%,我接受了这一点:)@havij当然,这不是问题,您仍然可以替换
sub(/@/,“>”);印刷品带有
打印“>”子字符串($0,2)
sed
解决方案运行得非常接近
awk
,但
fgrep
不正确,因为
@
出现在其他位置(除了
%4==0
行的开头),将其替换为
grep--no group separator-A1'^'infle|tr\>
提供的时间几乎与
awk
@havij相同:我在与GNU awk进行比较,您测试的是哪个版本的awk?
>1ab                                                                
2sdasd
>5fhd
6dhg
>9aghf
10adfgh