这里是代码,我知道它不是完美的perl。如果你知道我该如何做得更好,请告诉我。我的主要问题是如何在不使用Data:: dump的情况下打印出数组?
#!/usr/bin/perl
use Data::Dumper qw(Dumper);
use strict;
use warnings;
open(MYFILE, "<", "move_headers.txt") or die "ERROR: $!";
#First split the list of files and the headers apart
my @files;
my @headers;
my @file_list = <MYFILE>;
foreach my $source_parts (@file_list) {
chomp($source_parts);
my @parts = split(/:/, $source_parts);
unshift(@files, $parts[0]);
unshift(@headers, $parts[1]);
}
# Next get a list of unique headers
my @unique_files;
foreach my $item (@files) {
my $found = 0;
foreach my $i (@unique_files) {
if ($i eq $item) {
$found = 1;
last;
}
}
if (!$found) {
unshift @unique_files, $item;
}
}
@unique_files = sort(@unique_files);
# Now collect the headers is a list per file
my %hash_table;
for (my $i = 0; $i < @files; $i++) {
unshift @{ $hash_table{"$files[$i]"} }, "$headers[$i]";
}
# Process the list with regex
while ((my $key, my $value) = each %hash_table) {
if (ref($value) eq "ARRAY") {
print "$value", "n";
}
}
Perl文档有一个关于"打印数组的HASH "的教程(不使用Data::Dumper
)
perldoc perldsc
你在做一些艰难的事情。首先,散列已经统一了它的键,所以不需要循环来完成这个工作。看起来您正在构建文件的散列,其值意味着在这些文件中找到的头。输入数据是"filename:header",每行一个。(您可以使用哈希的哈希,因为头可能需要惟一化,但我们现在就不去管它了。)
use strict;
use warnings;
open my $files_and_headers, "<", "move_headers.txt" or die "Can't open move_headers: $!n";
my %headers_for_file;
while (defined(my $line = <$files_and_headers> )) {
chomp $line;
my($file, $header) = split /:/, $line, 2;
push @{ $headers_for_file{$file} }, $header;
}
# Print the arrays for each file:
foreach my $file (keys %headers_for_file) {
print "$file: @{ $headers_for_file{$file}}n";
}
我们让Perl在这里做大块的工作:
- 如果我们向哈希中添加键,它们总是唯一的。
- 如果我们在print语句中插入一个数组,Perl会在它们之间添加空格。
- 如果我们压入一个空的哈希元素,Perl会自动在元素中放入一个空的匿名数组,然后压入该元素。
使用Data::Dumper的替代方法是使用Data::Printer:
use Data::Printer;
p $value;
您还可以使用它来定制输出的格式。例如,您可以将所有内容放在一行中,而不需要索引(请参阅文档以获取更多选项):
use Data::Printer {
index => 0,
multiline => 0,
};
p $value;
另外,作为获得唯一文件的建议,将元素放入一个散列中:
my %unique;
@unique{ @files } = @files;
my @unique_files = sort keys %unique;
实际上,您甚至可以跳过这一步,一次将所有内容放入%hash_table中:
my %hash_table;
foreach my $source_parts (@file_list) {
chomp($source_parts);
my @parts = split(/:/, $source_parts);
unshift @{ $hash_table{$parts[0]} }, $parts[1];
}