【问题标题】:Check how many "," in each line in Perl [duplicate]检查Perl中每一行中有多少“,”[重复]
【发布时间】:2015-05-19 06:37:31
【问题描述】:

我必须检查文件中每一行中有多少次“,”。任何人都知道如何在 Perl 中做到这一点?

此时我的代码如下所示:

open($list, "<", $student_list)
while ($linelist = <$list>)
{
   printf("$linelist");
}
close($list)

但我不知道如何检查每个 $linelist 中有多少次 "," :/

【问题讨论】:

  • 还在代码的第一行和最后一行使用分号;

标签: perl file line


【解决方案1】:

在计数模式下使用transliteration operator

my $commas = $linelist =~ y/,//;

【讨论】:

    【解决方案2】:

    在您的代码中编辑:

    use warnings;
    use strict;
    
    open my $list, "<", "file.csv" or die $!;
    while (my $linelist = <$list>)
    {
        my $commas = $linelist =~ y/,//;
        print "$commas\n";
    }
    close($list);
    

    【讨论】:

      【解决方案3】:

      如果您只想计算文件中某些内容的数量,则无需将其读入内存。由于您没有更改文件,因此 mmap 就可以了:

      use File::Map qw(map_file);
      map_file my $map, $filename, '<';
      my $count = $map =~ tr/,//;
      

      【讨论】:

      • 您的代码也在将文件读入内存。您关于记忆的评论具有误导性。
      • 这是一种不同类型的内存,Perl 进程在处理完它后可以丢弃它。
      • Perl 进程不能丢弃它,内核可以。无论如何,句子you don't need to read it into memory 只是误导。在您的代码中,如果$map 后面的一些虚拟内存页面被释放,它会被整个读入内存并由内核决定。您错误地认为文件的部分不会被读入内存。
      【解决方案4】:
      #! perl
      # perl script.pl [file path]
      use strict;
      use warnings;
      my $file = shift or die "No file name provided";
      open(my $IN, "<", $file) or die "Couldn't open file $file: $!";
      my @matches = ();
      my $index = 0;
      # while <$IN> will get the file one line at a time rather than loading it all into memory
      while(<$IN>){
        my $line = $_;
        my $current_count = 0;
        # match globally, meaning keep track of where the last match was
        $current_count++ while($line =~ m/,/g);
        $matches[$index] = $current_count;
        $index++;
      }
      
      $index = 0;
      for(@matches){
        $index++;
        print "line $index had $_ matches\n" 
      }
      

      【讨论】:

        【解决方案5】:

        您可以使用mmap Perl IO 层代替File::Map。它几乎和以前一样高效,但很可能存在于您的 Perl 安装中,而无需安装模块。其次,在数组上下文中使用y///m//g 更有效。

        use strict;
        use warnings;
        use autodie;
        
        use constant STUDENT_LIST => 'text.txt';
        
        open my $list, '<:mmap', STUDENT_LIST;
        
        while ( my $line = <$list> ) {
            my $count = $line =~ y/,//;
            print "There is $count commas at $.. line.\n";
        }
        

        如果您想要语法正确的输出,您可以在正确的位置使用Lingua::EN::Inflect

        use Lingua::EN::Inflect qw(inflect);
        print inflect "There PL_V(is,$count) $count PL_N(comma,$count) at ORD($.) line.\n";
        

        示例输出:

        There are 7 commas at 1st line.
        There are 0 commas at 2nd line.
        There is 1 comma at 3rd line.
        There are 2 commas at 4th line.
        There are 7 commas at 5th line.
        

        【讨论】:

        • print Linuga::EN::Inflect::inflect "There PL_V(is,$commas) $commas PL_N(comma,$commas) at $.. line.\n"
        【解决方案6】:

        您想要文件中每一行的#commas,还是整个文件中的#commas?

        在每行的基础上,将您的 while 循环替换为:

        my @data = <list>;
        foreach my $line {
          my @chars = split //, $line;
          my $count = 0;
          foreach my $c (@chars) { $count++ if $c eq "," }
          print "There were $c commas\n";
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2011-10-06
          • 1970-01-01
          • 2018-07-09
          • 2017-04-21
          • 1970-01-01
          • 2019-06-25
          • 2017-07-13
          相关资源
          最近更新 更多