Perl中的字段/列比较

时间:2013-07-30 17:35:10

标签: perl comparison field

我想比较一个文件(file1)中列(col1)的值与另一个文件(file2)中列(col1)的所有记录。我的策略是读取文件中的每一行的文件,用制表符分隔符拆分并比较两列中的值。如果匹配,则从第二个文件中的列打印特定值,并将其附加到第一个文件的最后一列,否则打印“未找到”并将其附加到第一个文件的最后一列。 我认为我的以下脚本是比较行到行而不是行到字段中的所有行并返回错误(使用未初始化的值$ col1 [0] ...)。 非常感谢您的帮助。

open (FILE1, "<", "file1") or die ("Can't open file $!");
open (FILE2, "<", "file2") or die  ("Can't open file $!");
my @data1 = <FILE1>;
my @data2 = <FILE2>;
foreach my $curr_line_1 ( @data1 ) {
    my @col1 = split "\t", $curr_line_1;
    }
foreach my $curr_line_2 ( @data2 ) {
    my @col2 = split "\t", $curr_line_2;
    }
            if ("$col1[0]" eq "$col2[0]") {
                open FINAL, '>>', 'final';
                push(@col1, "$col2[1]");
                print FINAL "@col1\n";
                }
            else {
                open FINAL, '>>', 'final';
                push(@col1, "not found");
                print FINAL "@col1\n";
                }
close(FINAL);
close(FILE1);
close(FILE2);

file1    
1  mary
1  tom
2  john
3  will
4  hugh
5  eddy

file2
2  unit2
3  unitA
5  base

final
1  mary  not found
1  tom   not found
2  john  unit2
3  will  unitA
4  hugh  not found
5  eddy  base

1 个答案:

答案 0 :(得分:0)

我认为你的第一个for循环没有做任何事情。看起来它只是一遍又一遍地设置一个循环局部的变量。你有'使用严格'吗?当它到达$ col1 [0]时你应该收到一个警告,因为此时在范围内没有该名称的变量。也许不是使用那个循环,你可以做类似

的事情
my @data1_fields = map { [ split "\t", $_ ] } @data1;

然后在第二个循环中处理比较。

编辑:事实上,第二个列表可能会更好地作为哈希,然后这将使一切变得更容易。假设file2中每行的键都是唯一的,可以试试这个(未经测试):

my %data2_hash = ();
for (@data2) {
  $data2_hash{$_[0]} = $_[1];
}
for (@data1_fields) {
  # this is bad style, but w/e
  push(@{$_}, $data2_hash{$_[0]}) if exists $data2_hash{$_[0]};
}
open FINAL, '>>', 'final';
for (@data1_fields) {
  print FINAL join "\t", @{$_};
}