珀尔 : Counting Duplicates

标签 perl file count duplicates

我有以下文件.txt:

AAAA
BBBB
AAAA
CCCC
EEEE
AAAA

并且我已经编写了一个脚本来计算重复项的数量,将它们从最高的重复项到最低的重复项进行排序并打印它们。喜欢:

AAAA : 3
BBBB : 1
CCCC : 1
EEEE : 1

脚本是:

use v5.14;
use strict;

my %map;
chomp(my @chks = <FILE>);

foreach my $load (@chks) {
    $map{$load} += 1;
}

foreach my $key (sort keys %map) {
    say "$key : $map{$key} "
} 

但输出结果如下:

 : 3
 : 1
 : 1
 : 1

为什么看不到$key的值?

最佳答案

答案是您的输入文件来自使用 CR LF 作为行终止符的 Windows 平台。当在同一平台上使用 Perl 读取文件时,通常会在输入时删除 CR,但如果您使用 Linux 系统读取文件,那么它将保留在原位。 Perl 的 chomp 将只删除 LF,将 CR 留在每个散列键值的末尾。这将导致输出在打印 key 时被覆盖

解决方案是使用 :crlf PerlIO 层打开文件,或者使用 chomp

该程序肯定还有更多内容,因为您不会在任何地方打开 FILE。此外,您按照散列键的词法顺序而不是值的数字顺序对输出进行排序

这是我编写代码的方式。 :crlf 层导致 CR LF 行尾在输入时仅转换为 LF,chomp 现在将正常运行,只留下每行中的文本

use strict;
use warnings 'all';

my $filename = 'myfile.txt';

my @chks = do {
    open my $fh, '<:crlf', $filename or die qq{Unable to open "$filename" for input: $!};
    <$fh>;
};

chomp @chks;

my %map;

++$map{$_} for @chks;

for my $key ( sort { $map{$b} <=> $map{$a} } keys %map ) {
    print "$key : $map{$key}\n";
}

输出

AAAA : 3
CCCC : 1
BBBB : 1
EEEE : 1

正如我所说,除了使用 :crlf 层,您还可以使用 chomp @chks 替换为 s/\R\z//for @chks \R 将匹配来自任何系统的任何行终止符:在本例中为 CR LF 字符对

关于珀尔 : Counting Duplicates,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36529992/

相关文章:

xml - Perl:接收XPath元素的多个子级

perl - 在一段时间内readdir()产生的 “0”如何不为假?

java - 与 Java 的 XML 文件比较

java - 如何获取 mime 类型的 p7s 文件?

UNION查询的Mysql错误

java - 计算java中存档中的文件数

regex - 需要Perl正则表达式,它与从3.10.1.0开始的每个软件版本以及所有其他版本编号都匹配

perl - 安装失败,Perl 模块 Date::Calc

java - java中如何在一个文件中写入多次?

php - SilverStripe 3 过滤/过滤掉函数中的数据对象