读取文件后如何打印出文件中的特定字符?

发布于 2024-07-24 08:11:54 字数 545 浏览 5 评论 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;

I am reading a file using perl script. This file consists of strings with different characters and I am supposed to identify strings containing the character 'X'. I want to know how should I (1) print this string (containing 'X') and also (2) write this string to another file (3) count the number of 'X' characters in the whole file. The script below prints the whole file again. Any suggestions?

#!/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;

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

一向肩并 2024-07-31 08:11:54

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

#!/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__

更新:如果您不关心在每一行中查找具有一个或多个 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>;

Since this is code review, let's go one by one:

#!/use/bin/perl

That shebang line is most likely a typo. It should probably be

#!/usr/bin/perl

or whatever which perl returns on your system.

use strict;
use warnings;

Good.

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

No need for package global filehandles when you can use lexical filehandles. The 3-argument form of open is preferable these days. Also, the error message should indicate the file which you could not open:

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

my @body = <FILE>;

You are slurping the file into an array. That is completely unnecessary in this case.

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

Declare and initialize (if necessary) any variables in the smallest possible scope.

my $count;

The variable $string is not used anywhere else in your code.

foreach $_(@body){

This is silly. for uses $_ if no loop variable is specified. It is easier to keep things straight if you instead specify a lexical loop variable.

for my $line ( @body ) {

However, I do not think you should slurp the file.

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

That results in a successful match if the line contains an X. So, it is equivalent to /X/. However, that will not tell you the word that contained the 'X'. For that, you need to decide what a word is and do your matching at the word level.

With all that in mind, consider the following script. I have made a simplifying assumption regarding what I consider to be a word. You should be able to build on this to satisfy all the requirements:

#!/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: If you do not care about finding the words within each line that have one or more X characters, the while loop would be simplified:

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

by using $_. That, however, is probably inefficient (given that we are saving each matched X character). In this case, tr works best:

my ($count, $n);
$n = tr/X// and $count += $n and print while <$input>;
动次打次papapa 2024-07-31 08:11:54

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

You are printing $_ in both branches of your if-clause. Get rid of the else branch.

中二柚 2024-07-31 08:11:54

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

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;

Assuming "string" in your question equals "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;
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文