使用 perl 比较文件中的行

发布于 2024-10-21 16:56:49 字数 461 浏览 3 评论 0原文

我一直在尝试比较两个文件之间的行以及相同的匹配行。

由于某种原因,下面的代码只遍历“text1.txt”的第一行并打印“if”语句,无论两个变量是否匹配。

谢谢

use strict;
open( <FILE1>, "<text1.txt" );
open( <FILE2>, "<text2.txt" );
foreach my $first_file (<FILE1>) {
    foreach my $second_file (<FILE2>) {
        if ( $second_file == $first_file ) {
            print "Got a match - $second_file + $first_file";
        }
    }
}
close(FILE1);
close(FILE2);

Ive been trying to compare lines between two files and matching lines that are the same.

For some reason the code below only ever goes through the first line of 'text1.txt' and prints the 'if' statement regardless of if the two variables match or not.

Thanks

use strict;
open( <FILE1>, "<text1.txt" );
open( <FILE2>, "<text2.txt" );
foreach my $first_file (<FILE1>) {
    foreach my $second_file (<FILE2>) {
        if ( $second_file == $first_file ) {
            print "Got a match - $second_file + $first_file";
        }
    }
}
close(FILE1);
close(FILE2);

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

北恋 2024-10-28 16:56:49

如果比较字符串,请使用 eq 运算符。 "==" 以数字方式比较参数。

If you compare strings, use the eq operator. "==" compares arguments numerically.

三生一梦 2024-10-28 16:56:49

如果您的文件不太大,这里有一种方法可以完成这项工作。

#!/usr/bin/perl
use Modern::Perl;
use File::Slurp qw(slurp);
use Array::Utils qw(:all);
use Data::Dumper;

# read entire files into arrays
my @file1 = slurp('file1');
my @file2 = slurp('file2');

# get the common lines from the 2 files
my @intersect = intersect(@file1, @file2);

say Dumper \@intersect;

Here is a way to do the job if your files aren't too large.

#!/usr/bin/perl
use Modern::Perl;
use File::Slurp qw(slurp);
use Array::Utils qw(:all);
use Data::Dumper;

# read entire files into arrays
my @file1 = slurp('file1');
my @file2 = slurp('file2');

# get the common lines from the 2 files
my @intersect = intersect(@file1, @file2);

say Dumper \@intersect;
2024-10-28 16:56:49

一种更好更快(但内存效率较低)的方法是将一个文件读入散列,然后在散列表中搜索行。这样您只需检查每个文件一次。

# This will find matching lines in two files,
# print the matching line and it's line number in each file.

use strict;

open (FILE1, "<text1.txt") or die "can't open file text1.txt\n";
my %file_1_hash;
my $line;
my $line_counter = 0;

#read the 1st file into a hash 
while ($line=<FILE1>){
  chomp ($line); #-only if you want to get rid of 'endl' sign
  $line_counter++;
  if (!($line =~ m/^\s*$/)){
    $file_1_hash{$line}=$line_counter;
  }
}
close (FILE1);

#read and compare the second file
open (FILE2,"<text2.txt") or die "can't open file text2.txt\n";
$line_counter = 0;
while ($line=<FILE2>){
  $line_counter++;
  chomp ($line);
  if (defined $file_1_hash{$line}){
    print "Got a match: \"$line\"
in line #$line_counter in text2.txt and line #$file_1_hash{$line} at text1.txt\n";
  }
}
close (FILE2);

A better and faster (but less memory efficient) approach would be to read one file into a hash, and then search for lines in the hash table. This way you go over each file only once.

# This will find matching lines in two files,
# print the matching line and it's line number in each file.

use strict;

open (FILE1, "<text1.txt") or die "can't open file text1.txt\n";
my %file_1_hash;
my $line;
my $line_counter = 0;

#read the 1st file into a hash 
while ($line=<FILE1>){
  chomp ($line); #-only if you want to get rid of 'endl' sign
  $line_counter++;
  if (!($line =~ m/^\s*$/)){
    $file_1_hash{$line}=$line_counter;
  }
}
close (FILE1);

#read and compare the second file
open (FILE2,"<text2.txt") or die "can't open file text2.txt\n";
$line_counter = 0;
while ($line=<FILE2>){
  $line_counter++;
  chomp ($line);
  if (defined $file_1_hash{$line}){
    print "Got a match: \"$line\"
in line #$line_counter in text2.txt and line #$file_1_hash{$line} at text1.txt\n";
  }
}
close (FILE2);
失去的东西太少 2024-10-28 16:56:49

您必须重新打开或重置文件 2 的指针。将 openclose 命令移至循环内。

根据文件和行的大小,更有效的方法是仅循环一次文件并将文件 1 中出现的每一行保存在哈希中。然后检查文件 2 中的每一行是否存在该行。

You must re-open or reset the pointer of file 2. Move the open and close commands to within the loop.

A more efficient way of doing this, depending on file and line sizes, would be to only loop through the files once and save each line that occurs in file 1 in a hash. Then check if the line was there for each line in file 2.

纸短情长 2024-10-28 16:56:49

如果你想要行数,

my $count=`grep -f [FILE1PATH] -c [FILE2PATH]`;

如果你想要匹配的行,

my @lines=`grep -f [FILE1PATH]  [FILE2PATH]`;

如果你想要不匹配的行,

my @lines = `grep -f [FILE1PATH] -v [FILE2PATH]`;

If you want the number of lines,

my $count=`grep -f [FILE1PATH] -c [FILE2PATH]`;

If you want the matching lines,

my @lines=`grep -f [FILE1PATH]  [FILE2PATH]`;

If you want the lines which do not match,

my @lines = `grep -f [FILE1PATH] -v [FILE2PATH]`;
廻憶裏菂餘溫 2024-10-28 16:56:49

这是我编写的一个脚本,尝试查看两个文件是否相同,尽管可以通过使用代码并将其切换到 eq 来轻松修改它。正如 Tim 建议的那样,使用哈希可能会更有效,尽管您无法确保在不使用 CPAN 模块的情况下按照文件插入的顺序对文件进行比较(正如您所看到的,此方法实际上应该使用两个循环,但这对于我的目的来说已经足够了)。这并不是有史以来最伟大的脚本,但它可能会给您一个起点。


use warnings;

open (FILE, "orig.txt") 或死“无法打开第一个文件。\n”; @数据1 = ; 关闭(文件);

open (FILE, "2.txt") 或死“无法打开第二个文件。\n”; @数据2 = ; 关闭(文件);

for($i = 0; $i < @data1; $i++){ $data1[$i] =~ s/\s+$//; $data2[$i] =~ s/\s+$//; if ($data1[$i] ne $data2[$i]){ 打印“无法匹配行”。 ($i + 1) 。 “\n”; 打印$data1[$i]; print "不匹配:\n"; 打印$data2[$i]; print "\n程序中止!\n"; 出口; } }

print "\n文件是相同的。\n";

This is a script I wrote that tries to see if two file are identical, although it could easily by modified by playing with the code and switching it to eq. As Tim suggested, using a hash would probably be more effective, although you couldn't ensure the files were being compared in the order they were inserted without using a CPAN module (and as you can see, this method should really use two loops, but it was sufficient for my purposes). This isn't exactly the greatest script ever, but it may give you somewhere to start.


use warnings;

open (FILE, "orig.txt") or die "Unable to open first file.\n"; @data1 = ; close(FILE);

open (FILE, "2.txt") or die "Unable to open second file.\n"; @data2 = ; close(FILE);

for($i = 0; $i < @data1; $i++){ $data1[$i] =~ s/\s+$//; $data2[$i] =~ s/\s+$//; if ($data1[$i] ne $data2[$i]){ print "Failure to match at line ". ($i + 1) . "\n"; print $data1[$i]; print "Doesn't match:\n"; print $data2[$i]; print "\nProgram Aborted!\n"; exit; } }

print "\nThe files are identical. \n";

執念 2024-10-28 16:56:49

将您发布的代码转换为实际的 Perl 代码,这就是我的想法。

use strict;
use warnings;
use autodie;

open my $fh1, '<', 'text1.txt';
open my $fh2, '<', 'text2.txt';

while(
  defined( my $line1 = <$fh1> )
  and
  defined( my $line2 = <$fh2> )
){
  chomp $line1;
  chomp $line2;

  if( $line1 eq $line2 ){
    print "Got a match - $line1\n";
  }else{
    print "Lines don't match $line1 $line2"
  }
}

close $fh1;
close $fh2;

现在您可能真正想要的是两个文件的差异,最好留给 Text: :差异

use strict;
use warnings;

use Text::Diff;

print diff 'text1.txt', 'text2.txt';

Taking the code you posted, and transforming it into actual Perl code, this is what I came up with.

use strict;
use warnings;
use autodie;

open my $fh1, '<', 'text1.txt';
open my $fh2, '<', 'text2.txt';

while(
  defined( my $line1 = <$fh1> )
  and
  defined( my $line2 = <$fh2> )
){
  chomp $line1;
  chomp $line2;

  if( $line1 eq $line2 ){
    print "Got a match - $line1\n";
  }else{
    print "Lines don't match $line1 $line2"
  }
}

close $fh1;
close $fh2;

Now what you may really want is a diff of the two files, which is best left to Text::Diff.

use strict;
use warnings;

use Text::Diff;

print diff 'text1.txt', 'text2.txt';
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文