【问题标题】:Perl - Command line input and STDINPerl - 命令行输入和标准输入
【发布时间】:2011-12-13 23:35:24
【问题描述】:

我在下面为我的任务创建了这个脚本。它要求一个文本文件,检查单词的频率,并列出出现次数最多的 10 个单词。一切正常,但我需要这个脚本能够通过命令行和标准输入启动。

所以我需要能够编写“perl wfreq.pl example.txt”,这应该启动脚本而不是询问文本文件的问题。我不确定如何真正做到这一点。我想我可能需要一个 while 循环,如果你在终端命令行上给它一个文本文件,它会跳过 STDIN。

我该怎么做?

脚本

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

【问题讨论】:

    标签: perl command-line stdin


    【解决方案1】:

    您可以从&lt;&gt; 读取数据,而不是从&lt;STDIN&gt; 读取数据,以从命令行提供的文件或从标准输入(如果没有文件)获取数据。

    以程序为例:

    #!/usr/bin/env perl
    
    while (<>) {
      print $_;
    }
    

    命令./script foo.txt 将读取并打印来自foo.txt 的行,而./script 本身将读取并打印来自标准输入的行。

    【讨论】:

      【解决方案2】:

      您需要执行以下操作:

      my $DATA;
      my $filename = $ARGV[0];
      unless ($filename) {
          print "Enter filename:\n";
          $filename = <STDIN>;
          chomp $filename;
      }
      open($DATA, $filename) or die $!;
      

      虽然我不得不说,用户提示非常不像 Unix。

      【讨论】:

      • 这很好用,看起来就像我想要的。我的 $DATA;我的 $file = $ARGV[0]; if ($file) { open($DATA, $file) 或死 $!; } else { print "请输入文件名:\n" ; $数据=标准输入;我现在可以通过命令行 arg 启动它,但是当我在没有命令行 arg 的情况下启动它时,它只要求提供文件,但从未真正完成脚本的其余部分并进行排序和打印。 (适用于“perl wfreq2.pl example.txt”,但不适用于“perl wfreq2.pl”)
      • 不太确定我做错了什么,但是当我只说“perl wfreq.pl”时我无法启动它,它确实要求将文件作为标准输入,但它并没有移动它并进行实际的排序和列表。
      • @FictionFighter Dave Sherohman 的答案是您应该使用的答案。使用菱形 &lt;&gt; 运算符是可行的方法。
      【解决方案3】:
      perl script.pl < input.txt
      

      使用运算符&lt;input.txt 传递给script.pl 作为标准输入。然后,您可以跳过查询文件名。否则,使用$ARGV[0] 或类似名称,如果是defined

      【讨论】:

      • 这只会给我错误消息。 adm@adm-desktop:~/Desktop/perl$ perl wfreq2.pl 第 1 行没有这样的文件或目录。
      • 正如我所说,跳过查询文件名,然后在 while 循环中循环 &lt;&gt;
      • input.txt中有什么东西(即另一个文件的名称)吗?
      • 老实说,这比它需要的复杂得多。在您最喜欢的搜索引擎上阅读“perl 标准输入”。
      • 输入文本文件不包含要计数和列出的随机单词列表。
      【解决方案4】:

      您可以检查@ARGV 中的命令行参数,这是Perl 的自动获取命令行参数的数组,并且--如果存在-- 处理它们(否则继续来自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 的开头、遍历行、计算单词等)隔离到一个您可以轻松调用的子例程中(也许使用一个由文件名组成的参数)在代码的每个分支中。

      哦,为了确保我清楚这一点:always use strictalways use warnings。如果你不这样做,你就是在自找麻烦。

      【讨论】:

        猜你喜欢
        • 2012-03-16
        • 1970-01-01
        • 2014-02-02
        • 2021-04-29
        • 2010-09-09
        • 2021-06-24
        • 2010-09-13
        • 2021-05-11
        • 1970-01-01
        相关资源
        最近更新 更多