2016-09-02 35 views
0

而不是刪除重複的行,我有興趣刪除兩個文件之間找到的唯一行。這些文件具有不同的格式。Perl:刪除兩個文件之間的唯一行

文件1:

m160505_031746_42156_s1_p0|105337|10450_16161 
m160505_031746_42156_s1_p0|104750|20537_27903 
m160505_031746_42156_s1_p0|103809|17563_25308 
m160505_031746_42156_s1_p0|103217|8075_11486 

文件2(製表符分隔):

acCAATCCCATCACCATCtt m160505_031746_42156_s1_p0|105337|10450_16161 
atTAAAATACCATTATATgg m160505_031746_42156_s1_p0|104750|20537_27903 
caAACTCCAACTACGAACtg m160505_031746_42156_s1_p0|103809|17563_25308 
atCTATTTAAACCTAATCgg m160505_031746_42156_s1_p0|103217|8075_11486 
acCAATCCCATCACCATCtt m160505_031746_42156_s1_p0|152092|36592_40830 
atTAAAATACCATTATATgg m160505_031746_42156_s1_p0|143825|13009_23809 
caAACTCCAACTACGAACtg m160505_031746_42156_s1_p0|143710|0_20191 
atCTATTTAAACCTAATCgg m160505_031746_42156_s1_p0|140833|25358_34709 

文件2具有第2列中同一行作爲文件1中,通過20個字母中柱1之前第2列中的20個字母模式在文件2中重複(幾次,不止兩次),每次出現時都有唯一的相關序列。

我想將文件1中的序列與文件2中的第二列進行匹配。如果存在匹配,我想爲每個匹配生成一個包含兩列的新文件,保持關係文件2具有在兩列之間。實際上,我正在尋找只是刪除文件2中沒有文件1中列2匹配的行。

我意識到我的代碼需要幫助,但這裏是我迄今爲止給你更多的一個我如何思考的想法。我可能會最終需要使用散列,雖然我很擔心,因爲這樣做在列1的重複,所以我不想失去這些和他們的關係到第2列。

use strict; 
use warnings; 

open(OUT, '>', '/path/to/out.txt') or die $!; 
open(FMT0, '<', '/path/to/fmt0.txt') or die $!; 

my $regex = qr/m160505_.*/; 
while(my $line = <FMT0>){ 
    $line =~ $regex; 
    open(FMT6, '<', '/path/to/fmt6.txt') or die $!; 
    while(my $zero_fmt = <FMT6>){ 
      if ($zero_fmt =~ /([A-Z]{20})\t($line)/i){ 
        print OUT $zero_fmt; 
      } 
    } 
} 

感謝幫助!

+0

@Sebastian Lenartowicz謝謝你幫我清理我的問題了一下。 – Rob

回答

2

像這樣的東西可能會完成工作。 :-)

grep -f <(grep ^m160505_ file1) file2 

這裏有一個Perl的解決方案,因爲這就是你問:

#!/usr/bin/env perl 

use strict; 
use warnings; 

die "usage: $0 <file1> <file2>\n" 
    unless @ARGV == 2; 

open(my $file1, '<', $ARGV[0]) 
    or die "Could not open file1: $!\n"; 

my %keys; 
while (<$file1>) { 
    chomp; 
    $keys{$_} = 1 if /^m160505_/; 
} 

close($file1); 

open (my $file2, '<', $ARGV[1]) 
    or die "Could not open file2: $!\n"; 

while (<$file2>) { 
    chomp; 
    my ($key) = /\t(.+)$/; 
    print "$_\n" if $keys{$key}; 
} 

close($file2); 

在行動:

$ grep -f <(grep ^m160505_ file1) file2 
acCAATCCCATCACCATCtt m160505_031746_42156_s1_p0|105337|10450_16161 
atTAAAATACCATTATATgg m160505_031746_42156_s1_p0|104750|20537_27903 
caAACTCCAACTACGAACtg m160505_031746_42156_s1_p0|103809|17563_25308 
atCTATTTAAACCTAATCgg m160505_031746_42156_s1_p0|103217|8075_11486 

$ ./atgc.pl file1 file2 
acCAATCCCATCACCATCtt m160505_031746_42156_s1_p0|105337|10450_16161 
atTAAAATACCATTATATgg m160505_031746_42156_s1_p0|104750|20537_27903 
caAACTCCAACTACGAACtg m160505_031746_42156_s1_p0|103809|17563_25308 
atCTATTTAAACCTAATCgg m160505_031746_42156_s1_p0|103217|8075_11486 
+0

太棒了!謝謝。你對grep是正確的,但我非常感謝你的perl回答。所以很多人想要刪除重複的行,而不是唯一的行。我在這個問題上很難。你讓它看起來很簡單! :) – Rob

+0

在一個文件中查找與另一個文件中的行匹配的行是某種常見的Unix命令行任務,因此一旦您看過幾次,該解決方案就相當自然了!樂於幫助。 – mwp

相關問題