使用perl

时间:2018-06-06 05:23:29

标签: perl

我有一个格式如下的文件

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.我的脚本只打印第一个区域&#34; en_Au&#34;永远。 2.它应该能够测试文件是否为空,但如果文件是纯空的,则不输出任何内容,但如果我在文件中输入两个空行,则会打印两行&#34;没有可用的语言环境& #34;代替。 3.实际上在(!$ filed [2])部分我应该验证文件是否为空或者是否存在可用的语言环境,如果是,我是否需要在此处放置一些正则表达式来验证它是否也是一个语言环境? ? 希望有人能帮我解决这些问题!非常感谢!!!

1 个答案:

答案 0 :(得分:4)

最大缺失的是文件中的一个循环,然后您可以在其中一次处理一行。评论遵循代码。

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可以分配给列表中的变量。更好的是,使用here模块,它检查调用并允许更容易的接口更改。我将-a选项设置为&#34;标记,&#34;所以它只是设置一个变量($opt),如果给出的话。如果它应该具有可能的值,请使用'a=s' => \$opt并检查值。

  • 使用词汇文件句柄和三个参数Getopt::Longopen my $fh, '<', $file ...

  • die - 使用open

  • 打印错误die "... $!";
  • $! variable中使用时,"diamond" (angle) operator<$fh>$fh打开的文件中读取一行,如$line = <$fh>。当它读取一行时,它会在文件中前进一个指针,以便下次使用它时返回下一行。如果您在列表上下文中使用它,那么它将返回所有行,但是当您处理文件时,您通常希望逐行。

我所描述的一些逻辑和要求并不清楚,但希望上面的代码可以根据需要更容易调整。