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

时间:2017-10-02 17:05:05

标签: awk

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

@1ab
2sdasd
3asd
4asdf
@5fhd
6dhg
7ttht
8fgn
@9aghf
10adfgh

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

输出如下:

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

这是我的解决方案:

awk 'NR%4==1 || NR%4==2 {gsub("@",">"); print}' infile > outfile

有更快的方法吗?

3 个答案:

答案 0 :(得分:3)

Awk 解决方案:

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

outfile内容(针对您当前的输入):

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

答案 1 :(得分:2)

awk,带/出getline

$ cat infile
@1ab
2sdasd
3asd
4asdf
@5fhd
6dhg
7ttht
8fgn
@9aghf
10adfgh

$ awk 'FNR%4==1{sub(/@/,">");print; getline; print}' infile
>1ab
2sdasd
>5fhd
6dhg
>9aghf
10adfgh

# without using getline
awk 'f{print; f=0; next}FNR%4==1{sub(/@/,">");print; f=1; next}' infile
>1ab
2sdasd
>5fhd
6dhg
>9aghf
10adfgh
  

getline函数读取下一行并将脚本移动到   它,只是来自下一个输入记录的$0;设置NFNRFNRRT

答案 2 :(得分:1)

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

fgrep --no-group-separator -A1 '@' infile | tr @ \>

这比你的awk解决方案快一个数量级。

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

sed -n '1~4 { N; s/^@/>/p; }' infile

两种情况下的输出:

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