Perl从命令行输入多个文本文件并打印它们

时间:2014-05-19 22:39:25

标签: perl

我试图找到正(P)和负整数(N)的数量,包含所有小写字符(L)的单词数,所有大写字母(F),单词数与第一个字符大写,其余字符小写(U)。 按字母顺序排列的单词列表以及每次出现的行号和文件名以下示例说明了程序输入的程序输出。

文件1

Hello!  world  my  friend.  ALI  went  to  school.  Ali  has  -1 dollars and 10 TL

file2的

Hello  there  my  friend.  VELI  went  to  school.  Veli  has  10,  
dollars  and  -10,TL

运行程序后,

>prog.pl file1 file2

您获得的输出如下:

N=2
P=2
L=18
F=4
U=4

-----------
ali file1 (1 1)
and file1 (2) file2 (2)
dollars file1 (2) file2 (2)
friend file1 (1) file2 (1)
has file1 (1) file2 (1)
hello file1 (1) file2 (1)
my file1 (1) file2 (1)
school file1 (1) file2 (1)
there file2 (1)
tl file1 (2) file2 (2)
to file1 (1) file2 (1)
veli file2 (1 1)
went file1 (1) file2 (1)
world file1 (1)

我试着填写参赛作品,你能帮我处理吗?

#!/usr/bin/perl
$N= 0 ;
$P= 0 ;
$L= 0 ;
$F= 0 ;
$U= 0 ;
foreach __________ ( ____________) {__________________
        or die("Cannot opened because: $!") ;
    $lineno = 0 ;
    while($line=<>) {
        chomp ;
        $lineno++ ;
        @tokens = split $line=~ (/[ ,.:;!\?]+/) ;
        foreach $str (@tokens) {
            $N++ if ($str =~ /^-\d+$/) ;
            $P++ if ($str =~ /^\d+$/) ;
            $L++ if ($str =~ /^[a-z]+$/) ;
            $F++ if ($str =~ /^[A-Z][a-z]+$/) ;
            $U++ if ($str =~ /^[A-Z]+$/) ;
            if ($str =~ /^[a-zA-Z]+$/) {
                $str =~ __________________;
                if ( (____________________) || ($words{$str} =~ /\)$/ ) ) {
                    $words{$str} = $words{$str} . " " . $file . " (" . $lineno ;
                }
                else {_______________________________________;
                }}}}
    close(FH) ;
    foreach $w (__________________) {
        if ( ! ($words{$w} =~ /\)$/ )) {
            $words{$w} = ______________________;
        }}}
print "N=$N\n" ;
print "P=$P\n" ;
print "L=$L\n" ;
print "F=$F\n" ;
print "U=$U\n" ;
print "-----------\n" ;
foreach $w (sort(keys(%words))) {
    print $w," ", $words{$w}, "\n";
}

2 个答案:

答案 0 :(得分:2)

一些提示,我会让你继续前进......

Perl拥有所谓的钻石操作符。该操作符打开命令行上的所有文件(读入@ARGS数组),并逐行读取。

use strict;
use warnings;
use autodie;
use feature qw(say);

while my $line ( <> ) {
    chomp $line;
    say "The line read in is '$line'";
}

尝试此程序并按照您的程序运行它。看看会发生什么。

接下来,查看variables related to file handles的Perl文档。特别是看看$/变量。此变量用于破坏记录。它通常设置为换行符,因此当您读入文件时,您会逐行读取它。你可能想尝试一下。如果没有,你可以回到这样的事情:

use strict;
use warnings;
use autodie;
use feature qw(say);

while my $line ( <> ) {
    chomp $line;
    @words = split /\s+/, $line;
    for my $word ( @words ) {
        say "The word is '$word'";
    }
}

现在,您可以使用哈希来跟踪每个文件中的单词以及多少次。您还可以跟踪您提到的各种类型的单词。但是,请不要使用$U等变量。使用$first_letter_uppercase。这将在你的程序中有更多的意义,并且不会让你感到困惑。

你的老师教你几乎30年前写的Perl。这是在上帝创造互联网之前。 (嗯,不完全。互联网已经有10年了,但是除了少数学者之外没有人听说过它)。从那时起,Perl编程已经有了很大的发展。给自己写一本关于 Modern Perl(即Perl 5.x)的好书。

程序开头的 pragma 使用语句)执行以下操作:

  • use strict - 使用严格语法。这做了几件事,但主要的是确保你不能使用变量,除非你先声明它。 (最有可能使用my)。这可以防止错误,例如将$name放在一个地方,并在另一个地方引用$Name
  • use warnings - 这会警告您基本错误,例如您尝试使用未定义的变量。默认情况下,如果在算术上下文中使用它,则Perl假定变量为空字符串或等于零。当您尝试打印或检查尚未分配值的变量时。这可能意味着你有一个逻辑错误。

以上两个 pragma 将捕获90%的错误。

  • use autodie - 这将导致您的程序在许多情况下自动死亡。例如,您尝试打开一个不存在的文件进行读取。这样,您就不必记得检查某些操作是否成功失败的每个实例。
  • use feature qw(say) - 这样您就可以使用say代替printsay命令与print类似,但会在结尾处自动添加新行。它可以使您的代码更清晰,更容易理解。

例如:

print "N=$N\n" ;

VS。

say "N=$N" ;

答案 1 :(得分:0)

以下是我编写该程序的方法。但它不会给你很多分数,因为它与你的老师正在使用的“填空”方法相距甚远。但这很好,因为你老师的Perl很过时了。

#!/usr/bin/perl

use strict;
use warnings;
use 5.010;

my ($N, $P, $L, $F, $U);
my %words;

while (<>) {
  my @tokens = split /[^-\w]+/;
  foreach my $token (@tokens) {
    $N++ if $token =~ /^-\d+$/;
    $P++ if $token =~ /^\d+$/;
    next unless $token =~ /[a-z]/i;
    $L++ if $token eq lc $token;
    $U++ if $token eq uc $token;
    $F++ if $token eq ucfirst lc $token;
    push @{$words{lc $token}{$ARGV}}, $.;
  }
  close ARGV if eof;
}

say "N=$N";
say "P=$P";
say "L=$L";
say "F=$F";
say "U=$U";

for my $word (sort { $a cmp $b } keys %words) {
  print "$word ";
  for my $file (sort { $a cmp $b } keys %{$words{$word}} ) {
    print "$file (", join(' ', @{$words{$word}{$file}}), ') ';
  }
  print "\n";
}