我有以下格式的文件
locale,English,en_AU,6251
locale,French,fr_BE,25477
charmap,English,EN,5423
Run Code Online (Sandbox Code Playgroud)
而且我想使用perl在文件后跟选项“ -a”打印出一些内容并输出类似
Available locales:
en_Au
fr_BE
EN
Run Code Online (Sandbox Code Playgroud)
为此,我在下面有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);
Run Code Online (Sandbox Code Playgroud)
我在这里有三个问题。1.我的脚本将永远只打印第一个语言环境“ en_Au”。2.它应该能够测试文件是否为空,但是如果文件是完全空的,则什么都不输出,但是如果我在文件中输入两行空行,则会打印两行“无可用语言环境”。3.实际上,在(!$ filed [2])部分中,我应该验证文件是否为空或不存在可用的语言环境,如果是,我是否需要在此处放置一些正则表达式以验证它是否也是语言环境? ?希望有人可以帮助我解决这些问题!非常感谢!!!
丢失的最大事情是文件中各行之间的循环,然后您一次要处理一行。注释遵循代码。
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;
}
Run Code Online (Sandbox Code Playgroud)
这将打印所需的输出。(这是$fields[2]您真正需要的简单条件吗?)
评论
总是有use warnings;和use strict;开始
我不建议使用单字母变量名称。人们会忘记它们的含义,这会使代码更难遵循,而且很容易犯出愚蠢的错误
该@ARGV可分配给变量在列表中。更好的方法是使用Getopt :: Long模块,该模块检查调用并允许更轻松的界面更改。我将-a选项设置为“标志”,因此只要设置了变量($opt)就可以设置它。如果那应该有可能的值,请使用'a=s' => \$opt并检查一个值。
使用词法文件句柄和三个参数open,open my $fh, '<', $file ...
当die-ing打印错误,die "... $!";使用$!变量
的“钻石”(角度)算子,<$fh>,读取一条线从与打开的文件$fh中使用时标量上下文,如在$line = <$fh>。它在读取一行时在文件中前进一个指针,以便在下次使用它时返回下一行。如果在列表上下文中使用它,则它将返回所有行,但是在处理文件时,通常需要逐行进行。
我尚不清楚其中描述的一些逻辑和要求,但是希望上面的代码将更易于根据需要进行调整。