假设我有一个大文件(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
有更快的方法吗?
答案 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
;设置NF
,NR
,FNR
,RT
答案 2 :(得分:1)
如果at字符仅作为“记录分隔符”出现,则可以使用fgrep
和tr
,例如:
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