朋友需要帮助。关注我的INPUT TEXT FILE
Andrew UK
Cindy China
Rupa India
Gordon Australia
Peter New Zealand
将记录存在于目录中时,将上述内容转换为哈希并写回文件。我试过跟随(它不起作用)。
#!/usr/perl/5.14.1/bin/perl
use strict;
use warnings;
use Data::Dumper;
my %hash = ();
my $file = ".../input_and_output.txt";
my $people;
my $country;
open (my $fh, "<", $file) or die "Can't open the file $file: ";
my $line;
while (my $line =<$fh>) {
my ($people) = split("", $line);
$hash{$people} = 1;
}
foreach my $people (sort keys %hash) {
my @country = $people;
foreach my $c (@country) {
my $c_folder = `country/test1_testdata/17.26.6/$c/`;
if (-d $cad_root){
print "Exit\n";
} else {
print "NA\n";
}
}
答案 0 :(得分:3)
这是主要问题:
my ($people) = split("", $line);
您正在使用空字符串进行拆分,并且您将返回值分配给单个变量(最终将以每行的第一个字符结束)。
相反,您应该在split
上' '
(a special pattern的单个空格字符):
作为另一种特殊情况,...当PATTERN被省略或由单个空格字符组成的字符串(例如
' '
或"\x20"
,而不是/ /
)时。在这种情况下,EXPR中的任何前导空格都会在拆分发生之前被删除,而PATTERN则被视为/\s+/
;特别是,这意味着任何连续的空格(不只是一个空格字符)都被用作分隔符。
限制返回的字段数,以确保包含空格的国家/地区名称的完整性:
#!/usr/bin/env perl
use strict;
use warnings;
my @people;
while (my $line = <DATA>) {
$line =~ /\S/ or next;
$line =~ s/\s+\z//;
push @people, [ split ' ', $line, 2 ];
}
use YAML::XS;
print Dump \@people;
__DATA__
Andrew UK
Cindy China
Rupa India
Gordon Australia
Peter New Zealand
将条目添加到数组中以便1)保留输入顺序; 2)两个同名但来自不同国家的人不会导致一个条目丢失。
如果订单不重要,您可以在每个条目的数组引用中使用键入国家/地区名称的哈希值和人名。现在,我将承担订单问题(如果你付出更多努力来制定一个明确的问题,它会帮助我们。)
现在有一个选项是浏览人 - 国家/地区对列表,并打印目录country/test1_testdata/17.26.6/$c/
所存在的所有对(顺便提一下,在您的代码中)
my $c_folder = `country/test1_testdata/17.26.6/$c/`;
那将尝试执行一个名为country/test1_testdata/17.26.6/$c/
的程序,如果它产生任何结果,则将其输出保存在$c_folder
中。故事的道德:在编程中,精确性很重要。仅仅因为`
看起来像'
,这并不意味着你可以用一个来表示另一个。)
鉴于你的问题集中在哈希上,我使用了一系列对匿名哈希的引用来存储下面代码中的人 - 国家对列表。我缓存查找结果以减少您需要点击磁盘的次数。
#!/usr/bin/env perl
use strict;
use warnings;
@ARGV == 2 ? run( @ARGV )
: die_usage()
;
sub run {
my $people_data_file = shift;
my $country_files_location = shift;
open my $in, '<', $people_data_file
or die "Failed to open '$people_data_file': $!";
my @people;
my %countries;
while (my $line = <$in>) {
next unless $line =~ /\S/; # ignore lines consisting of blanks
$line =~ s/\s+\z//;# remove all trailing whitespace
my ($name, $country) = split ' ', $line, 2;
push @people, { name => $name, country => $country };
$countries{ $country } = undef;
}
# At this point, @people has a list of person-country pairs
# We are going to use %countries to reduce the number of
# times we need to check the existence of a given directory,
# assuming that the directory tree is stable while this program
# is running.
PEOPLE:
for my $person ( @people ) {
my $country = $person->{country};
if ($countries{ $country }) {
print join("\t", $person->{name}, $country), "\n";
}
elsif (-d "$country_files_location/$country/") {
$countries{ $country } = 1;
redo PEOPLE;
}
}
}
sub die_usage {
die "Need data file name and country files location\n";
}
现在,这方面有很多变化,这就是为什么 你 制定一个清晰简洁的问题非常重要,以便人们试图帮助你回答<强烈> 你的 具体问题,而不是每个人在他们看到问题时提出他/她自己的问题解决方案。例如,人们也可以这样做:
#!/usr/bin/env perl
use strict;
use warnings;
@ARGV == 2 ? run( @ARGV )
: die_usage()
;
sub run {
my $people_data_file = shift;
my $country_files_location = shift;
open my $in, '<', $people_data_file
or die "Failed to open '$people_data_file': $!";
my %countries;
while (my $line = <$in>) {
next unless $line =~ /\S/; # ignore lines consisting of blanks
$line =~ s/\s+\z//;# remove all trailing whitespace
my ($name, $country) = split ' ', $line, 2;
push @{ $countries{$country} }, $name;
}
for my $country (keys %countries) {
-d "$country_files_location/$country"
or delete $countries{ $country };
}
# At this point, %countries maps each country for which
# we have a data file to a list of people. We can then
# print those quite simply so long as we don't care about
# replicating the original order of lines from the original
# data file. People's names will still be sorted in order
# of appearance in the original data file for each country.
while (my ($country, $people) = each %countries) {
for my $person ( @$people) {
print join("\t", $person, $country), "\n";
}
}
}
sub die_usage {
die "Need data file name and country files location\n";
}
答案 1 :(得分:-1)
如果你想要的是哈希中的名字计数器,那么我找到了你,伙计! 我不会尝试其余代码,因为您正在检查记录文件夹 我无法访问,所以我无法解决任何问题。
我看到你的一个问题。看看这个:
#!/usr/bin/env perl
use strict;
use warnings;
use feature 'say'; # Really like using say instead of print because no need for newline.
my $file = 'input_file.txt';
my $fh; # A filehandle.
my %hash;
my $people;
my $country;
my $line;
unless(open($fh, '<', $file)){die "Could not open file $_ because $!"}
while($line = <$fh>)
{
($people, $country) = split(/\s{2,}/, $line); # splitting on at least two spaces
say "$people \t $country"; # Just printing out the coolumns in the file or people and Country.
$hash{$people}++; # Just counting all the people in the hash.
# Seeing how many unique names there are, like is there more than one Cindy, etc ...?
}
say "\nNow I'm just sorting the hash of people by names.";
foreach(sort{$a cmp $b} keys %hash)
{
say "$_ => $hash{$_}"; # Based on your file. The counter is at 1 because nobody has the same names.
}
这是输出。正如你所看到的,我通过分割至少两个空格来解决问题,因此国名不会被删除。
Andrew UK
Cindy China
Rupa India
Gordon Australia
Peter New Zealand
Andrew United States
Now I'm just sorting the hash of people by names.
Andrew => 2
Cindy => 1
Gordon => 1
Peter => 1
Rupa => 1
我在文件中添加了另一个Andrew。这个安德鲁来自美国 如你看到的。我看到你的一个问题。看看这个:
my ($people) = split("", $line);
您正在拆分字符,因为这些引号之间没有空格。 如果你现在看一下这个变化,你就会分裂至少一个空间。
my ($people) = split(" ", $line);