0

我正在使用 perl 脚本读取文件。该文件由具有不同字符的字符串组成,我应该识别包含字符“X”的字符串。我想知道我应该如何(1)打印这个字符串(包含'X')以及(2)把这个字符串写入另一个文件(3)计算整个文件中'X'字符的数量。下面的脚本再次打印整个文件。有什么建议么?

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

open (FILE, "/home/user/Desktop/infile.phy") || die "cant open file\n";
my @body = <FILE>;
close (FILE);
my $count= 0;
my $string = '';
foreach $_(@body){
    if ($_ =~ m/[X]/){
        print "$_";
        $count++;
        print $count;
    }
    else {
        print ;
    }
}
exit;
4

3 回答 3

4

由于这是代码审查,让我们一一进行:

#!/use/bin/perl

那个shebang线很可能是一个错字。应该是

#!/usr/bin/perl

或您系统上的任何which perl返回。

use strict;
use warnings;

好的。

open (FILE, "/home/user/Desktop/infile.phy") || die "cant open file\n";

当您可以使用词法文件句柄时,不需要包全局文件句柄。的 3 参数形式open现在更可取。此外,错误消息应指示您无法打开的文件:

my $filename = '/home/user/Desktop/infile.phy';
open my $input, '<', $filename
    or die "Cannot open '$filename' for reading: $!";

my @body = <FILE>;

您正在将文件放入数组中。在这种情况下,这是完全没有必要的。

my $count  = 0;
my $string = '';

在尽可能小的范围内声明和初始化(如有必要)任何变量。

my $count;

该变量$string不会在代码中的其他任何地方使用。

foreach $_(@body){

这很愚蠢。for如果没有指定循环变量,则使用 $_。如果您改为指定词法循环变量,则更容易保持直截了当。

for my $line ( @body ) {

但是,我认为您不应该啜饮该文件。

        if ($_ =~ m/[X]/){

如果该行包含一个 X,这将导致成功匹配。因此,它相当于/X/. 但是,这不会告诉您包含“X”的单词。为此,您需要确定单词是什么并在单词级别进行匹配。

考虑到所有这些,请考虑以下脚本。我对我认为是一个词的东西做了一个简化的假设。您应该能够在此基础上满足所有要求:

#!/usr/bin/perl

use strict;
use warnings;

my $filename = "$ENV{TEMP}/test.txt";
open my $input, '<', $filename
    or die "Cannot open '$filename' for reading: $!";

my $count;

while ( my $line = <$input> ) {
    my @words = grep { /X/ } split /\b/, $line;
    $count += @words;
    print join(', ', @words), "\n";
}

print "$count\n";

__END__

更新:如果您不关心在每一行中找到具有一个或多个 X 字符的单词,则 while 循环将被简化:

while ( <$input> ) { 
    $count += (my @matches = /(X)/g );
    print if @matches;
}

通过使用 $_。然而,这可能是低效的(假设我们正在保存每个匹配的 X 字符)。在这种情况下,tr效果最好:

my ($count, $n);
$n = tr/X// and $count += $n and print while <$input>;
于 2009-06-09T13:36:49.360 回答
1

您正在 if 子句的两个分支中打印$_。摆脱 else 分支。

于 2009-06-09T13:21:52.540 回答
0

假设您的问题中的“字符串”等于“行”:

use strict;
use warnings;

@ARGV=qw(/home/user/Desktop/infile.phy);

my $count = 0;
open my $outfile, '>', 'outfile' or die $!;
while (<>) {
  my $cnt = tr/X/X/;
  if ($cnt) {
    print;
    print $outfile $_;
  }
  $count += $cnt;
}

close $outfile or die $!;

print $count;
于 2009-06-09T13:29:58.920 回答