比较分隔文件第一列中的数据并打印出第二个文件

时间:2015-06-04 00:15:29

标签: perl shell

我需要帮助才能找到一个执行相同功能的perl脚本 SORT命令:sort –t’;’ –k1,1 File1.txt File2.txt File2.txt | uniq –u

我有两个用分号分隔的文件。我需要仅根据第一列(数字)的唯一性提取出唯一的行.File2.txt(差异而不是),另一列column2和column3在此期间无关紧要。

File1.txt(主文件)

123;winter;season
456;fall;season
789;autumn;season
321;summer;season
654;dry;weather
987;cold;weather

File2.txt

123;winter;season
456;fall;season
789;autumn;season
321;summer;season
369;march;month
147;september;month

预期输出(369& 147不在File1.txt中)

369;march;month
147;september;month

到目前为止我已经写过,但它打印出文件二;

#!/usr/bin/perl

# create names lookup table from first file
open(DATA, "<File1.txt") or die "Couldn't open file File1.txt, $!";
my %names;
while (<DATA>) {
    (my @data)= split /;/, $_;
     $names{$data} = 1;
   last if eof;
}

# scan second file
open(DATA2, "<File2.txt") or die "Couldn't open file File2.txt, $!";
while (<DATA2>) {

    print if /^(\d+)/ && not $data[0];
    }
}

我仍然很难理解阵列和哈希。任何帮助改善我的代码将不胜感激。请添加评论或指出我有的任何错误...提前感谢。,

1 个答案:

答案 0 :(得分:0)

你离我不远。

  • 在第一个循环中,将分号分隔的字段放在数组@data中,然后编写

    $names{$data} = 1;
    

    但是$data是一个单独的变量,此时未定义。你想要

    $names{$data[0]} = 1;
    

    使用@data数组的第一个元素

  • 在第二个循环中,您测试$data[0]不再存在,因为您在上部循环中声明了@data。由于你的正则表达式捕获 $1中的第一个字段,你可以说

    print if /^(\d+)/ and not $names{$1};
    

    ,您的计划将有效

每个Perl程序顶部的use strictuse warnings也是必需。该措施会产生一些警告信息,帮助您解决上述错误。您还应该使用词法文件句柄和open的三参数形式。并且您的last if eof行是不必要的,因为无论如何while条件都会退出循环。

这里已经应用了这些修补程序重写了您的程序

#!/usr/bin/perl

use strict;
use warnings;

open my $f1_fh, '<', 'File1.txt' or die "Couldn't open file File1.txt: $!";
my %names;
while (<$f1_fh>) {
    my @data = split /;/, $_;
    $names{$data[0]} = 1;
}

open my $f2_fh, '<', 'File2.txt' or die "Couldn't open file File2.txt: $!";
while ( <$f2_fh> ) {
    print if /^(\d+)/ and not $names{$1};
}

<强>输出

369;march;month
147;september;month