阅读文件后,如何在文件中打印出特定字符?

时间:2009-06-09 13:14:08

标签: perl file-handling string-matching

我正在使用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;

3 个答案:

答案 0 :(得分: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";

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

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__

UPDATE:如果您不关心在每行中找到包含一个或多个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>;

答案 1 :(得分:1)

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

答案 2 :(得分:0)

假设你的问题中的“字符串”等于“line”:

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;