Python 基于模式删除文件中的重复行

Python 基于模式删除文件中的重复行,python,perl,Python,Perl,我试图找到一个好方法来实现这一点,但不幸的是,我没有找到一个 我正在使用以下格式的文件: =集群= 规范PRD000681;PRIDE_Exp_Complete_Ac_22491.xml;频谱=1074真 规范PRD000681;PRIDE_Exp_Complete_Ac_22498.xml;频谱=2950真 =集群= 规范PRD000681;PRIDE_Exp_Complete_Ac_22498.xml;频谱=1876真 规范PRD000681;PRIDE_Exp_Complete_Ac_22

我试图找到一个好方法来实现这一点,但不幸的是,我没有找到一个

我正在使用以下格式的文件:

=集群=
规范PRD000681;PRIDE_Exp_Complete_Ac_22491.xml;频谱=1074真
规范PRD000681;PRIDE_Exp_Complete_Ac_22498.xml;频谱=2950真

=集群=
规范PRD000681;PRIDE_Exp_Complete_Ac_22498.xml;频谱=1876真
规范PRD000681;PRIDE_Exp_Complete_Ac_22498.xml;频谱=3479真
规范PRD000681;PRIDE_Exp_Complete_Ac_22498.xml;频谱=3785真

=集群=
规范PRD000681;PRIDE_Exp_Complete_Ac_22493.xml;频谱=473真
规范PRD000681;PRIDE_Exp_Complete_Ac_22493.xml;频谱=473真

正如您所看到的,每个等级库行都是不同的,除了最后一行,其中字符串谱的数量是重复的。 我想做的是获取模式
=Cluster=
之间的每个信息块,并检查是否有重复频谱值的行。如果有多行重复,则删除除一行之外的所有行

输出文件应如下所示:

=集群=
规范PRD000681;PRIDE_Exp_Complete_Ac_22491.xml;频谱=1074真
规范PRD000681;PRIDE_Exp_Complete_Ac_22498.xml;频谱=2950真

=集群=
规范PRD000681;PRIDE_Exp_Complete_Ac_22498.xml;频谱=1876真
规范PRD000681;PRIDE_Exp_Complete_Ac_22498.xml;频谱=3479真
规范PRD000681;PRIDE_Exp_Complete_Ac_22498.xml;频谱=3785真

=集群=
规范PRD000681;PRIDE_Exp_Complete_Ac_22493.xml;频谱=473真

我用它来分割文件,但我不知道如何检查是否有重复的频谱

#!/usr/bin/perl

undef $/;
$_ = <>;
$n = 0;

for $match (split(/(?==Cluster=)/)) {
      open(O, '>temp' . ++$n);
      print O $match;
      close(O);
}
#/usr/bin/perl
未定义$/;
$_ = ;
$n=0;
对于$match(拆分(/(?==群集=)/){
打开(O,'>temp'+$n);
打印$match;
关闭(O);
}

PD:我使用Perl是因为它对我来说更容易,但我也理解python

类似的内容将删除重复的行(在文件中全局删除)

在拆分集群时,您可以做一些非常类似的事情,但只需:

  if ( $line =~ m/==Cluster==/ ) { 
     open ( $output, ">", "temp".$count++ ); 
     select $output;
  }
这会将默认的“打印”位置设置为
$output
(您也需要在循环之外声明它)

你亦应:

  • 使用严格;
    使用警告;
  • 避免将
    读入
    $\uu
    ,这是不必要的。但如果必须这样做,通常最好是
    $block=do{local$/};
    。然后
    $block=~m/regex/
  • 使用词汇文件句柄:
    open(my$output,“>”,“filename”)或die$!;
  • 在打开时检查您的返回代码(
    或die$!
    通常就足够了)
这大概是这样的:

#!/usr/bin/perl

use warnings;
use strict;

my %seen; 
my $count = 0; 
my $output; 

while (  <> ) {
  next if ( m/spectrum=(\d+)/ and $seen{$1}++ );
  if ( m/==Cluster==/ ) { 
     open ( $output, ">", "temp".$count++ ) or die $!; 
     select $output;
  }
  print;
}
!/usr/bin/perl
使用警告;
严格使用;
我看到的百分比;
我的$count=0;
我的美元产出;
而(){
下一个if(m/spectrum=(\d+)/和$seen{$1}++);
如果(m/==Cluster===/){
打开($output,“>”,“temp”。$count++)或die$!;
选择$output;
}
印刷品;
}

类似的内容将删除重复的行(在文件中全局删除)

在拆分集群时,您可以做一些非常类似的事情,但只需:

  if ( $line =~ m/==Cluster==/ ) { 
     open ( $output, ">", "temp".$count++ ); 
     select $output;
  }
这会将默认的“打印”位置设置为
$output
(您也需要在循环之外声明它)

你亦应:

  • 使用严格;
    使用警告;
  • 避免将
    读入
    $\uu
    ,这是不必要的。但如果必须这样做,通常最好是
    $block=do{local$/};
    。然后
    $block=~m/regex/
  • 使用词汇文件句柄:
    open(my$output,“>”,“filename”)或die$!;
  • 在打开时检查您的返回代码(
    或die$!
    通常就足够了)
这大概是这样的:

#!/usr/bin/perl

use warnings;
use strict;

my %seen; 
my $count = 0; 
my $output; 

while (  <> ) {
  next if ( m/spectrum=(\d+)/ and $seen{$1}++ );
  if ( m/==Cluster==/ ) { 
     open ( $output, ">", "temp".$count++ ) or die $!; 
     select $output;
  }
  print;
}
!/usr/bin/perl
使用警告;
严格使用;
我看到的百分比;
我的$count=0;
我的美元产出;
而(){
下一个if(m/spectrum=(\d+)/和$seen{$1}++);
如果(m/==Cluster===/){
打开($output,“>”,“temp”。$count++)或die$!;
选择$output;
}
印刷品;
}

如果重复的行是连续的,您可以使用以下perl oneliner:

perl -ani.back -e 'next if defined($p) && $_ eq $p;$p=$_;print' file.txt 

原始文件是备份,扩展名为
。back

如果重复的行是连续的,您可以使用以下perl oneliner:

perl -ani.back -e 'next if defined($p) && $_ eq $p;$p=$_;print' file.txt 

原始文件是备份,扩展名为
。back

您还可以使用我在
itertools
模块中使用的
groupby
脚本

我假设您的输入文件名为
f_input.txt
,输出文件名为
new_file.txt

from itertools import groupby

data = (k.rstrip().split("=Cluster=") for k in open("f_input.txt", 'r'))
final = list(k for k,_ in groupby(list(data)))

with open("new_file.txt", 'a') as f:
    for k in final:
        if k == ['','']:
            f.write("=Cluster=\n")
        elif k == ['']:
            # write '\n\n' in Windows and '\n' in Linux (tested only in Windows!)
            f.write("\n\n")
        else:
            f.write("{}\n".join(k))

输出文件
new_file.txt
将与您所需的输出类似。

您也可以使用我在
itertools
模块中使用的
groupby
脚本

我假设您的输入文件名为
f_input.txt
,输出文件名为
new_file.txt

from itertools import groupby

data = (k.rstrip().split("=Cluster=") for k in open("f_input.txt", 'r'))
final = list(k for k,_ in groupby(list(data)))

with open("new_file.txt", 'a') as f:
    for k in final:
        if k == ['','']:
            f.write("=Cluster=\n")
        elif k == ['']:
            # write '\n\n' in Windows and '\n' in Linux (tested only in Windows!)
            f.write("\n\n")
        else:
            f.write("{}\n".join(k))

输出文件
new_file.txt
将与所需的输出类似。

该任务似乎很简单,不需要perl/python:使用命令删除相邻的重复行:

$ uniq < input.txt > output.txt
$uniqoutput.txt

这项任务似乎很简单,不需要perl/python:使用命令删除相邻的重复行:

$ uniq < input.txt > output.txt
$uniqoutput.txt

重复行是连续的吗?重复行是连续的吗?谢谢你的否决票!这个答案怎么了?@Toto不知道…我给你一个;)@Enrique:谢谢你。谢谢你。谢谢你的否决票!这个答案怎么了?@Toto不知道…我给你一个;)@Enrique:谢谢。这项工作也完成了,但这个脚本也删除了规范。我只是想删除重复的行,而不是重复的词。这项工作也一样,但这个脚本删除