【问题标题】:print specific INFILE area using perl使用 perl 打印特定的 INFILE 区域
【发布时间】:2018-06-06 05:23:28
【问题描述】:

我有一个格式如下的文件

locale,English,en_AU,6251
locale,French,fr_BE,25477
charmap,English,EN,5423

我想使用 perl 打印出带有选项“-a”的文件,并输出类似的东西

Available locales:
en_Au
fr_BE
EN

为此,我有下面的 perl 脚本

$o = $ARGV[0];
$f = $ARGV[1];
open (INFILE, "<$f") or die "error";
my $line = <INFILE>;
my @fields = split(',', $line);
if($o eq "-a"){
  if(!$fields[2]){print "No locales available\n";}
  else{print "Available locales: \n";
    while($fields[2]){print "$fields[2]\n";}
  }
}
close(INFILE);

我在这里有三个问题。 1. 我的脚本将永远只打印第一个语言环境“en_Au”。 2.它应该能够测试一个文件是否为空,但是如果一个文件是纯空的,它什么也不输出,但是如果我在文件中输入两个空行,它会打印两行“没有可用的语言环境”。 3.事实上,在 (!$filed[2]) 部分,我应该验证文件是否为空或不存在可用的语言环境,如果是,我是否需要在此处放置一些正则表达式来验证它是否也是语言环境? ? 希望有人能帮我弄清楚这些!非常感谢!!!

【问题讨论】:

  • 代码只读取一行,my $line = &lt;INFILE&gt;;。它需要一个循环,其中一行接一行地读取,while (my $line = &lt;INFILE&gt;) { ... } 其余的似乎都很好。但是,如果它没有第三个字段,为什么不跳过该行呢? (这真的是一个很好的条件吗?)就像next if not $fields[2];。然后,整个事情需要用现代 Perl 重写。
  • 每次循环都可以将所需的字段存储在一个数组中,并在循环后将其全部打印出来。或者,当然,您可以在每行找到它们时打印它们。 (代码中while 循环在$fields[2] 上没有意义。)
  • @zdim 你好,zdim,一开始我试过用while,但是一直输出“en_AU”
  • 发表了一个答案,但我不明白你需要什么的一些解释。告诉我进展如何

标签: perl


【解决方案1】:

最大的缺失是文件中的行循环,然后您一次处理一行。注释跟在代码后面。

use warnings;
use strict;
use feature 'say';
use Getopt::Long;

#my ($opt, $file) = @ARGV;  # better use a module
my ($opt, $file);
Getoptions( 'a' => \$opt, 'file=s' => \$file ) or usage();
usage() if not $file;  # mandatory argument    

open my $fh, '<', $file  or die "Can't open $file: $!";

while (my $line = <$fh>) {
    chomp $line;
    my @fields = split /,/, $line;
    next if not $fields[2];
    if ($opt) {
        say $fields[2];
    }   
}
close $fh;

sub usage {
    say STDERR "Usage: $0 [-a] --file filename";
    exit 1;
}

这将打印所需的输出。 ($fields[2] 上的这个简单条件真的是你所需要的吗?)

评论

  • 开头总是有use warnings;use strict;

  • 我不推荐使用单字母变量名。人们忘记了它们的意思,这使代码更难理解,而且很容易犯愚蠢的错误

  • @ARGV 可以分配给列表中的变量。更好的是,使用Getopt::Long 模块,它检查调用并允许更容易的接口更改。我将-a 选项设置为“标志”,因此它只设置一个变量($opt)(如果已给出)。如果它应该有可能的值,请使用 'a=s' =&gt; \$opt 并检查值。

  • 使用词法文件句柄和三个参数openopen my $fh, '&lt;', $file ...

  • die-ing 打印错误die "... $!";,使用$! variable

  • "diamond" (angle) operator&lt;$fh&gt;scalar context 中使用时,从使用$fh 打开的文件中读取一行,如$line = &lt;$fh&gt;。它在读取一行时推进文件中的一个指针,以便下次使用它时返回下一行。如果您在 list context 中使用它,那么它会返回所有行,但是当您处理文件时,您通常希望逐行进行。

一些描述的逻辑和要求对我来说不是很清楚,但希望上面的代码会更容易根据需要进行调整。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-09-19
    • 1970-01-01
    • 2016-01-03
    • 2012-02-14
    • 1970-01-01
    • 2014-11-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多