Perl:比较两个文件中的单词

Perl:比较两个文件中的单词,perl,file-io,stdout,Perl,File Io,Stdout,这是我当前的脚本,用于尝试将文件\u all.txt中的单词与file2.txt中的单词进行比较。它应该打印出文件中所有不在文件2中的单词 我需要将它们格式化为每行一个单词,但这不是更紧迫的问题 我是Perl的新手。。。我得到了更多的C和Python,但这有点棘手,我知道我的变量赋值是关闭的 use strict; use warnings; my $file2 = "file_all.txt"; %I know my assignment here is wrong my $fi

这是我当前的脚本,用于尝试将
文件\u all.txt
中的单词与
file2.txt
中的单词进行比较。它应该打印出
文件中所有不在
文件2中的单词

我需要将它们格式化为每行一个单词,但这不是更紧迫的问题

我是Perl的新手。。。我得到了更多的C和Python,但这有点棘手,我知道我的变量赋值是关闭的

 use strict;
 use warnings;

 my $file2 = "file_all.txt";   %I know my assignment here is wrong
 my $file1 = "file2.txt";

 open my $file2, '<', 'file2' or die "Couldn't open file2: $!";
 while ( my $line = <$file2> ) {
     ++$file2{$line};
     }

 open my $file1, '<', 'file1' or die "Couldn't open file1: $!";
 while ( my $line = <$file1> ) {
     print $line unless $file2{$line};
     }
使用严格;
使用警告;
my$file2=“file_all.txt”;%我知道我的作业错了
my$file1=“file2.txt”;
打开我的$file2,“你就快到了

%
符号表示散列。不能将文件名存储在散列中,需要标量

my $file2 = 'file_all.txt';
my $file1 = 'file2.txt';
您需要一个散列来计算出现的次数

my %count;
要打开文件,请指定其名称-它存储在标量中,还记得吗

open my $FH, '<', $file2 or die "Can't open $file2: $!";

问题在于以下两行:

 my %file2 = "file_all.txt";
 my %file1 = "file2.txt";
在这里,您将一个在Perl中称为a的值分配给一个散列(由
%
sigil表示)。散列由由箭头运算符(=>)分隔的键值对组成。e、 g

散列需要偶数个参数,因为必须同时给它们一个键和一个值。您当前只给每个散列一个值,因此会抛出此错误

要为标量赋值,请使用
$
符号:

 my $file2 = "file_all.txt";
 my $file1 = "file2.txt";
您的错误消息:

将变量与一起使用

然后,将常见任务分解为子例程。在这种情况下,您需要的是:1)使用文件名并返回该文件中的单词表的函数,以及2)使用文件名和查找表并打印文件中但未显示在查找表中的单词的函数

#!/usr/bin/env perl

use strict;
use warnings;

use Carp qw( croak );

my @filenames = qw(file_all.txt file2.txt);

print "$_\n" for @{ words_notseen(
    $filenames[0],
    words_from_file($filenames[1])
)};

sub words_from_file {
    my $filename = shift;
    my %words;

    open my $fh, '<', $filename
        or croak "Cannot open '$filename': $!";

    while (my $line = <$fh>) {
        $words{ lc $_ } = 1 for split ' ', $line;
    }

    close $fh
        or croak "Failed to close '$filename': $!";

    return \%words;
}

sub words_notseen {
    my $filename = shift;
    my $lookup = shift;

    my %words;

    open my $fh, '<', $filename
        or croak "Cannot open '$filename': $!";

    while (my $line = <$fh>) {
        for my $word (split ' ', $line) {
            unless (exists $lookup->{$word}) {
                $words{ $word } = 1;
            }
        }
    }

    return [ keys %words ];
}
#/usr/bin/env perl
严格使用;
使用警告;
使用鲤鱼qw(croak);
my@filenames=qw(file_all.txt file2.txt);
为@{words\u notseen打印“$\u\n”(
$filenames[0],
单词\u来自\u文件($filename[1])
)};
子单词\u来自\u文件{
我的$filename=shift;
我的%字;

打开我的$fh,“正如你在问题中提到的:它应该打印出
文件中所有
文件2中没有的单词

下面的小代码执行以下操作:

#!/usr/bin/perl
use strict;
use warnings;

my ($file1, $file2) = qw(file_all.txt file2.txt);

open my $fh1, '<', $file1 or die "Can't open $file1: $!";
open my $fh2, '<', $file2 or die "Can't open $file2: $!";

while (<$fh1>)
{
    last if eof($fh2);
    my $compline = <$fh2>;
    chomp($_, $compline);
    if ($_ ne $compline)
    {
        print "$_\n";
    }
}
file2.txt:

zz
yy
ee
ef
pp
df
输出:

ab
cd
gh

看起来您的思路是正确的。问题是什么?如果我尝试运行它,我会在缺席.pl第6行的哈希分配中得到奇数个元素。在缺席.pl第7行的哈希分配中得到奇数个元素。无法打开文件2:缺席.pl第9行没有这样的文件或目录。我不太确定这意味着什么,因为我是perl新手(若这是一个愚蠢的问题,那个么很抱歉!)在我看来,你们夸大了自己对C和Python的掌握程度。我尝试过这样做,并用my$file替换了最上面的两行……但我得到了“my”变量$file2掩码,前面的声明位于同一范围内的缺席.pl第9行。“my”变量$file1屏蔽了同一作用域中位于缺席.pl第14行的早期声明。全局符号“%file2”要求在缺席.pl第11行显示包名。全局符号“%file2”在缺席.pl第16行需要显式的包名。我将最上面的一个更改为$file2,但仍然得到相同的错误。我做错了什么?我尝试在这里解决一下,第二个也是$FH还是其他什么?(对不起,我感觉像一个使用perl的两岁小孩)@user3295674:如果不并行读取文件,则可以使用相同的文件句柄。这太棒了!我如何确保不会将CAt与CAt分开计算?(大小写不重要)在那之后,我想我会选择你的答案,这是最简洁的工作模式!我想你可以自己检查一下。这将对猫和猫一样。 "my" variable $file2 masks earlier declaration in same scope at absent.pl line 9. "my" variable $file1 masks earlier declaration in same scope at absent.pl line 14. Global symbol "%file2" requires explicit package name at absent.pl line 11. Global symbol "%file2" requires explicit package name at absent.pl line 16. Execution of absent.pl aborted due to compilation errors.
 my @filenames = qw(file_all.txt file2.txt);
#!/usr/bin/env perl

use strict;
use warnings;

use Carp qw( croak );

my @filenames = qw(file_all.txt file2.txt);

print "$_\n" for @{ words_notseen(
    $filenames[0],
    words_from_file($filenames[1])
)};

sub words_from_file {
    my $filename = shift;
    my %words;

    open my $fh, '<', $filename
        or croak "Cannot open '$filename': $!";

    while (my $line = <$fh>) {
        $words{ lc $_ } = 1 for split ' ', $line;
    }

    close $fh
        or croak "Failed to close '$filename': $!";

    return \%words;
}

sub words_notseen {
    my $filename = shift;
    my $lookup = shift;

    my %words;

    open my $fh, '<', $filename
        or croak "Cannot open '$filename': $!";

    while (my $line = <$fh>) {
        for my $word (split ' ', $line) {
            unless (exists $lookup->{$word}) {
                $words{ $word } = 1;
            }
        }
    }

    return [ keys %words ];
}
#!/usr/bin/perl
use strict;
use warnings;

my ($file1, $file2) = qw(file_all.txt file2.txt);

open my $fh1, '<', $file1 or die "Can't open $file1: $!";
open my $fh2, '<', $file2 or die "Can't open $file2: $!";

while (<$fh1>)
{
    last if eof($fh2);
    my $compline = <$fh2>;
    chomp($_, $compline);
    if ($_ ne $compline)
    {
        print "$_\n";
    }
}
ab
cd
ee
ef
gh
df
zz
yy
ee
ef
pp
df
ab
cd
gh