0

我目前正在尝试获取文本文件的用户参数(通常为 2 个),从文本文件中获取字符、行和单词的数量并将它们显示回来。我的代码目前将它们全部添加在一起,而不是为每个文件单独列出它们。如何根据用户参数列出文件名,以及每个文件的行数、字符数和单词数,而不将它们加在一起?感谢您花时间阅读本文。

#!usr/bin/perl -w
use strict;
my $user_files = @ARGV;
chomp($user_files);

my @parts;
my $word_count = 0;
my $total_words = 0;
my $line_count = 0;

foreach my $line (<>)
{
    @parts = split (/\s+/,$line);
    $line_count += (line =~tr/\n//);
    $word_count += length($line) + 1;
    $total_words += scalar(@parts);
}

for(my $i = 0; $i < 1; $i++)
{
    print "File name:",       @ARGV, 
        "\t\t Word Count: ",  $word_count, 
        "\t\t Total words: ", $total_words, 
        "\t\t Total lines: ", $line_count, 
        "\n";

} 
4

2 回答 2

5

您需要更改两项基本内容才能使其正常工作。

  1. 使用$ARGV- 当使用跨多个文件读取时<>,它包含当前文件的名称
  2. 将数据存储在哈希中(即键控$ARGV

在这个示例中,我保留了您的所有计算(但我认为您需要重新考虑其中的一些),并进行了一些其他更改以稍微清理您的代码。

#!/usr/bin/perl

use strict;
use warnings; # better than '-w'

my %files; # Store all the data here

# While is better than foreach here as is reads the file one line at a time.
# Each line goes into $_
while (<>) {
    # By default, split splits $_ on whitespace
    my @parts = split;
    # By default, tr/// works on $_
    $files{$ARGV}{line_count} += tr/\n//;
    # I think this calculation is wrong.
    # length() has no relation to word count. And why add 1 to it?
    $files{$ARGV}{word_count} += length($_) + 1;
    # Addition imposes scalar context, no need for the scalar keyword
    $files{$ARGV}{total_words} += @parts;
}

# Print all the information in the hash
foreach (keys %files) {
    print "File name: $_",
        "\t\t Word Count: $files{$_}{word_count}",
        "\t\t Total words: $files{$_}{total_words}",
        "\t\t Total lines: $files{$_}{line_count}",
        "\n";
}
于 2013-04-03T10:04:15.963 回答
2

这一行:

foreach my $line(<>) 

正在从 STDIN 获取输入。您需要执行以下操作:

for my $file (@user_files) {
     open my $fin, '<', $file or die $!;
     while ( my $line = <$fin> ) {
         # count stuff
     }
     close $fin;
     # print counted stuff
}

另请注意,如果您想将多个文件名作为参数:

my $user_files = @ARGV;

只会采用第一个参数。你可能想要:

my @user_files = @ARGV;

此外,chompon 一个 arg 是不必要的。

在您的脚本中,您在打印之前计算所有文件。这很好,但您可能希望将该数据存储在数组或散列中。该数据结构可能如下所示:

$file_counts = [
    {
        $file_name1 => {
            characters => $characters,
            words      => $words,
            lines      => $lines,
        }
    },
    {
        $file_name2 => {
            characters => $characters,
            words      => $words,
            lines      => $lines,
        }
    },
];
于 2013-04-02T19:34:33.643 回答