[英]perl - how to read mulitple files in a directory and store data to a unique variable
[英]Perl word count for mulitple files
我必須顯示字符,單詞和行的數量,然后將它們總計在格式化的printf的底部。 不知何故,當我放入兩個要計數的文件時,它只會打印出一個計數。 同樣,當它應該為每個文件顯示單獨的計數時,我似乎只是將計數加在一起,然后在末尾將它們加在一起。 我正在從命令控制台輸入文件,所以它將是perl mywc.pl
這就是我所擁有的,我確定我在循環中丟失了一些東西,但是我無法弄清楚是什么。
#!usr/bin/perl
use warnings;
use strict;
my $text_lines = 0;
my $words = 0;
my $chars = 0;
my $counter = 0;
my $total_word = 0;
my $total_char = 0;
my $total_line = 0;
printf ("%-15s", "Files");
printf ("%15s", "Characters");
printf ("%15s", "Words");
printf ("%15s", "Lines\n");
while ($counter < scalar(@ARGV))
{
open(INPUT, '<', $ARGV[$counter]) or die "Cannot open file!";
my @doc = <INPUT>;
foreach my $lines (@doc)
{
$text_lines++;
$chars += length ($lines);
$words += scalar(split(/\s+/, $lines));
}
printf ("%-15s", "$ARGV[$counter]");
printf ("%15s", "$chars");
printf ("%15s", "$words");
printf ("%15s", "$text_lines\n");
$total_word += $words;
$total_char += $chars;
$total_line += $text_lines;
close INPUT;
$counter++;
}
printf ("%-15s", "TOTAL");
printf ("%15s", "$total_char");
printf ("%15s", "$total_word");
printf ("%15s", "$total_line\n");
#print "Characters: $chars\n";
#print "Words: $words\n";
#print "Lines: $text_lines\n";
不知何故,當我放入兩個要計數的文件時,它只會打印出一個計數。
這不是真的。
$ script .bashrc .bash_profile
Files Characters Words Lines
.bashrc 2146 317 89
.bash_profile 3339 502 148
TOTAL 5485 819 237
(必須修復shebang路徑,因為它必須是絕對路徑。)
我確定自己在循環中遺漏了一些東西,但我無法弄清楚是什么。
但是,這是事實。 您的結果不正確。 正確的計數如下:
$ wc .bashrc .bash_profile
89 289 2146 .bashrc
59 174 1193 .bash_profile
148 463 3339 total
您會注意到第一個文件的行數和字符數正確,但第二個文件的行數和字符數正確。 這是因為您忘記了重置每個文件的計數。
(忽略單詞,因為可能使用了“單詞”的不同定義。)
將以下各行移動到您的外部循環中,因為它們僅適用於正在檢查的文件:
my $text_lines = 0;
my $words = 0;
my $chars = 0;
我相信您希望計算通過命令行傳遞的每個文件中的字符,單詞和行數。
但是代碼的問題是您要全局聲明所有變量,在處理完所有文件后,只有總計數變量必須是全局變量,其他變量應該在處理每個文件之前在本地聲明。在處理完每個單個文件后重新確定范圍,並在下一個文件上再次重新初始化。
第二件事, my @doc = <INPUT>
這里您將整個文件都保存在內存中,根本不需要。
我將如下處理:
#!/usr/bin/perl
use strict;
use warnings;
print "No files provided\n" unless(@ARGV);
my ($total_word,$total_char,$total_line)=(0,0,0);
printf ("%-15s", "Files");
printf ("%15s", "Characters");
printf ("%15s", "Words");
printf ("%15s", "Lines\n");
foreach my $file (@ARGV){
open my $fh, '<', $file or die "unable to open file $file: $!\n";
#Declare variables separately here for each file
my($words,$chars,$lines)=(0,0,0);
while(my $line=<$fh>){
$lines++;
$chars += length ($line);
$words += scalar(split(/\s+/, $line));
}
printf ("%-15s", $file);
printf ("%15s", $chars);
printf ("%15s", $words);
printf ("%15s", "$lines\n");
$total_word += $words;
$total_char += $chars;
$total_line += $lines;
close $fh;
}
printf ("%-15s", "TOTAL");
printf ("%15s", "$total_char");
printf ("%15s", "$total_word");
printf ("%15s", "$total_line\n");
我將使用Perl的while (<>) { ... }
構造以及$ARGV
變量。
#!/usr/bin/perl
use strict;
use warnings;
print "No files provided\n" unless(@ARGV);
my ($total_word,$total_char,$total_line)=(0,0,0);
printf ("%-15s", "Files");
printf ("%15s", "Characters");
printf ("%15s", "Words");
printf ("%15s", "Lines\n");
my %file_counts;
my @files = @ARGV; # Take a copy
while (<>) {
$file_counts{$ARGV}{lines}++;
$file_counts{$ARGV}{chars} += length;
$file_counts{$ARGV}{words} += split;
}
foreach (@files) {
printf ("%-15s", $_);
printf ("%15s", $file_counts{$_}{chars});
printf ("%15s", $file_counts{$_}{words});
printf ("%15s", "$file_counts{$_}{lines}\n");
$total_char += $file_counts{$_}{chars};
$total_word += $file_counts{$_}{words};
$total_line += $file_counts{$_}{lines};
}
printf ("%-15s", "TOTAL");
printf ("%15s", "$total_char");
printf ("%15s", "$total_word");
printf ("%15s", "$total_line\n");
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.