【问题标题】:Find what word appeared more than once查找多次出现的单词
【发布时间】:2015-02-27 18:14:19
【问题描述】:

我有一个文本文件,其中每一行都是一组逗号分隔的单词。我需要知道一个词是否被重复,如果是,在哪几行重复。示例:

word1, word2, word3, word4, word5
word6, word4, word7, word8

输出:

word4: 1,2

我正在试验一个 perl 脚本,它在逐行读取文件时创建从单词到行号的映射,但我想知道是否有更简单的方法。

【问题讨论】:

  • 一个单词可以在一行出现两次吗?例如word1, word1, word2....
  • @TLP:在我的应用程序中,每个单词在一行中只出现一次。

标签: regex linux string perl shell


【解决方案1】:

您需要阅读所有行才能打印任何内容,所以您描述的是您必须做的事情,但事实证明它非常简单。

my %seen;
while (<>) {
   for (split /\s*,\s*/) {
      push @{ $seen{$_} }, $.;
   }
}

for my $word (keys(%seen)) {
   next if @{ $seen{$word} } < 2;
   print($word . ": " . join(",", @{ $seen{$word} }) . "\n");
}

【讨论】:

  • 我认为您的意思是next unless(或&lt;=),否则您会排除匹配超过1个的单词。
  • 我想您在编写 Perl 代码时会谨慎选择。 print 语句中的括号和点运算符的原因是什么?我自己会选择printf
  • @Borodin,甚至从未将其视为一种选择。 printf("%s: %s\n", $word, join(",", @{ $seen{$word} })); 确实可能更清晰一点,尽管 : 和换行符在现有代码中很突出。
【解决方案2】:

使用 Perl 单行:

perl -F/,\s*/ -lanE 'push @{$w{$_}}, $. for @F; }{ say "$_: @{$w{$_}}" for grep {@{$w{$_}} > 1} sort keys %w' words.txt

开关

  • -F: -a 开关的 split() 模式(//'s 是可选的)
  • -l:启用行尾处理
  • -a:在空间上分割行并将它们加载到数组中@F
  • -n:为输入文件中的每个“行”创建一个 while(&lt;&gt;){...} 循环。
  • -e:告诉perl 在命令行上执行代码。 (-E 启用所有可选功能)

【讨论】:

  • 米勒回来了! +1 因为单行可以解释。
猜你喜欢
  • 2018-09-23
  • 1970-01-01
  • 2014-11-08
  • 1970-01-01
  • 1970-01-01
  • 2021-04-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多