所以我在下面为我的作业创建了这个脚本,它要求一个文本文件并检查单词的频率并列出出现次数最多的10个单词。一切正常,但我需要这个脚本能够通过命令行以及标准输入启动。
所以我需要能够编写'perl wfreq.pl example.txt',这应该启动脚本而不是问一个文本文件的问题。我不确定如何实现这一点,我想如果你在终端命令行中给它文本文件,我可能需要一个跳过STDIN的开始某处的while循环。
任何有帮助的人?
#! /usr/bin/perl
use utf8;
use warnings;
print "Please enter the name of the file: \n" ;
$file = <STDIN>;
chop $file;
open(my $DATA, "<:utf8", $file) or die "Oops!!: $!";
binmode STDOUT, ":utf8";
while(<$DATA>) {
tr/A-Za-z//cs;
s/[;:()".,!?]/ /gio;
foreach $word (split(' ', lc $_)) {
$freq{$word}++;
}
}
foreach $word (sort { $freq{$b} <=> $freq{$a} } keys %freq) {
@fr = (@fr, $freq{$word});
@ord = (@ord, $word);
}
for ($v =0; $v < 10; $v++){
print " $fr[$v] | $ord[$v]\n";
}
答案 0 :(得分:8)
您可以从<STDIN>
读取,而不是从<>
读取,以从命令行提供的文件或stdin中获取数据(如果没有文件)。
#!/usr/bin/env perl
while (<>) {
print $_;
}
命令./script foo.txt
将读取并打印来自foo.txt
的行,而./script
本身将读取并打印来自stdin的行。
答案 1 :(得分:6)
只有在未提供文件名时才能读取STDIN:
my $DATA;
my $filename = $ARGV[0];
if ($filename) {
open($DATA, $filename) or die $!;
} else {
$DATA = STDIN;
}
好的,我误解了这个问题,根据您的评论,您需要执行以下操作:
my $DATA;
my $filename = $ARGV[0];
unless ($filename) {
print "Enter filename:\n";
$filename = <STDIN>;
chomp $filename;
}
open($DATA, $filename) or die $!;
虽然我不得不说,用户提示非常不像unix那样。
答案 2 :(得分:0)
你可以做的是检查@ARGV
中的命令行参数,它是自动获取命令行参数的Perl数组,以及 - 如果存在 - 处理它们(否则继续输入{{1} }})。类似的东西:
STDIN
请注意,您可能希望隔离用于处理文件名的代码(即use utf8;
use strict; #Don't ever forget this! Always, always, ALWAYS use strict!
use warnings;
if(@ARGV)
{
#Assume that the first command line argument is a file to be processed as in your original code.
#You may or may not want to care if additional command line arguments are passed. Up to you.
}
else
{
#Ask for the filename and proceed as normal.
}
的开头,通过行,计算单词等)到您可以轻松调用的子例程(可能与代码的每个分支中包含文件名的参数。
哦,为了确保我清楚这一点:始终 DATA
和始终 use strict
。如果你不这样做,那你就是在寻找麻烦。
答案 3 :(得分:0)
perl script.pl < input.txt
运算符<
的使用将input.txt
传递给script.pl
作为标准输入。然后,您可以跳过查询文件名。否则,请使用$ARGV[0]
或类似内容,如果defined
。