删除文件中的行之间的string

我有这样的文件:

ATOM 2517 O VAL 160 8.337 12.679 -2.487 ATOM 2518 OXT VAL 160 7.646 12.461 -0.386 TER ATOM 2519 N VAL 161 -14.431 5.789 -25.371 ATOM 2520 H1 VAL 161 -15.336 5.698 -25.811 ATOM 2521 H2 VAL 161 -13.416 10.529 17.708 ATOM 2522 H3 VAL 161 -14.363 9.436 18.498 ATOM 2523 CA VAL 161 4.400 9.233 16.454 ATOM 2524 HA VAL 161 3.390 9.170 16.047 

我必须删除“TER”之前的行,并在TER之后的行之后的三行,并使文件连续如下:

 ATOM 2517 O VAL 160 8.337 12.679 -2.487 ATOM 2519 N VAL 161 -14.431 5.789 -25.371 ATOM 2523 CA VAL 161 4.400 9.233 16.454 ATOM 2524 HA VAL 161 3.390 9.170 16.047 

只要删除TER开始的行。

  sed -i.bak '/^\s*TER\s*$/d' transrotate/myfiles 

如果你只是想删除空行,试试这个:

 sed -i.bak '/^\s*$/d' transrotate/myfiles 
 sed '/^TER/d' yourFile 

会做这项工作

 kent$ echo "ATOM 2517 O VAL 160 8.337 12.679 -2.487 dquote> ATOM 2518 OXT VAL 160 7.646 12.461 -0.386 dquote> TER dquote> ATOM 2519 N VAL 161 -14.431 5.789 -25.371 dquote> ATOM 2520 H1 VAL 161 -15.336 5.698 -25.811 dquote> ATOM 2521 H2 VAL 161 -13.416 10.529 17.708 dquote> ATOM 2522 H3 VAL 161 -14.363 9.436 18.498" |sed '/^TER/d' ATOM 2517 O VAL 160 8.337 12.679 -2.487 ATOM 2518 OXT VAL 160 7.646 12.461 -0.386 ATOM 2519 N VAL 161 -14.431 5.789 -25.371 ATOM 2520 H1 VAL 161 -15.336 5.698 -25.811 ATOM 2521 H2 VAL 161 -13.416 10.529 17.708 ATOM 2522 H3 VAL 161 -14.363 9.436 18.498 

根据新的要求更新

请参阅下面的awk行:

 kent$ cat t.txt ATOM 2517 O VAL 160 8.337 12.679 -2.487 ATOM 2518 OXT VAL 160 7.646 12.461 -0.386 TER ATOM 2519 N VAL 161 -14.431 5.789 -25.371 ATOM 2520 H1 VAL 161 -15.336 5.698 -25.811 ATOM 2521 H2 VAL 161 -13.416 10.529 17.708 ATOM 2522 H3 VAL 161 -14.363 9.436 18.498 kent$ awk 'NR==FNR{if ($0~/^TER/)a[NR]=1;}NR>FNR{f=0;for(x in a){if(FNR>=x-1 && FNR<=x+3){f=1;break;}}if(!f){print $0;}f=0}' t.txt t.txt ATOM 2517 O VAL 160 8.337 12.679 -2.487 ATOM 2522 H3 VAL 161 -14.363 9.436 18.498 

再次更新

我希望这是最新的更新:

awk行:

 awk 'NR==FNR{if ($0~/^TER/)a[NR]=1;}NR>FNR{f=0;for(x in a){if(FNR==x-1 || FNR==x || (FNR>x+1 && FNR<=x+4)){f=1;break;}}if(!f){print $0;}f=0}' yourFile yourFile 

测试:

 kent$ cat t.txt ATOM 2517 O VAL 160 8.337 12.679 -2.487 ATOM 2518 OXT VAL 160 7.646 12.461 -0.386 TER ATOM 2519 N VAL 161 -14.431 5.789 -25.371 ATOM 2520 H1 VAL 161 -15.336 5.698 -25.811 ATOM 2521 H2 VAL 161 -13.416 10.529 17.708 ATOM 2522 H3 VAL 161 -14.363 9.436 18.498 ATOM 2523 CA VAL 161 4.400 9.233 16.454 ATOM 2524 HA VAL 161 3.390 9.170 16.047 kent$ awk 'NR==FNR{if ($0~/^TER/)a[NR]=1;}NR>FNR{f=0;for(x in a){if(FNR==x-1 || FNR==x || (FNR>x+1 && FNR<=x+4)){f=1;break;}}if(!f){print $0;}f=0}' t.txt t.txt ATOM 2517 O VAL 160 8.337 12.679 -2.487 ATOM 2519 N VAL 161 -14.431 5.789 -25.371 ATOM 2523 CA VAL 161 4.400 9.233 16.454 ATOM 2524 HA VAL 161 3.390 9.170 16.047 

蛮力似乎是不受欢迎的,但是这里无论如何,

 perl -e 'undef $/; ($a=<>)=~s!(.*\n){1}TER\n(.*\n)(.*\n){3}!$2!; print $a;' INFILE > OUTFILE 

当然这个方法假定输入文件适合RAM。


PS如果输入大于RAM,那么需要一个简单的状态机。 在循环中逐行读取文件。 pushpush入中间缓冲区。 如果缓冲区中有多于4行,则shift并打印头部。 如果缓冲区中的第二行是TER且缓冲区包含4行,请清除缓冲区。 有线时重复。

对于这样的事情, ed是很棒的:

 $ ed -s file.txt <<EOF > /^TER/d > -1d > +1d > d > d > ,p > EOF 

倒数第二行的p将打印结果; 将其更改为w进行编辑并保存到相同的文件。