Perl用字符串读写文本文件

Perl用字符串读写文本文件,perl,Perl,朋友需要帮助。跟随我的输入文本文件 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 = ".../inp

朋友需要帮助。跟随我的输入文本文件

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";
    }
 }

如果你想要的是散列中的名字计数器,那我就抓住你了,伙计

我不会尝试代码的其余部分,因为您正在检查记录文件夹 我没有权限,所以我无法拍摄任何比这更麻烦的东西

我看到了你的一个问题。看看这个:

#!/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 columns 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. 
}
my ($people) = split("", $line);
我在档案里又添了一个安德鲁。这位安德鲁来自美国 如你所见。我看到了你的一个问题。看看这个:

#!/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 columns 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. 
}
my ($people) = split("", $line);
您正在拆分字符,因为这些引号之间没有空格。 如果您现在查看此更改,则至少在一个空间上拆分

 my ($people) = split(" ", $line);

这是主要问题:

my ($people) = split("", $line);
您正在使用空字符串进行拆分,并将返回值分配给单个变量,该变量将以每行的第一个字符结束

相反,应在“”上拆分一个空格字符,该字符为:

作为另一个特例。。。当模式被省略或由单个空格字符(如“”或\x20)组成的字符串,但不是例如//时。在这种情况下,EXPR中的任何前导空格都会在分割发生之前被删除,而模式会被视为是/\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
它将尝试执行一个名为country/test1_testdata/17.26.6/$c/的程序,并将其输出保存在$c_文件夹中(如果它产生任何输出)。这个故事的寓意是:在编程中,精确性很重要。仅仅因为‘看起来像’,并不意味着你可以用一个来表示另一个

考虑到您的问题集中在散列上,我使用匿名散列的一系列引用来存储下面代码中的人员-国家对列表。我缓存查找结果,以减少需要访问磁盘的次数

#!/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";
}

它怎么不起作用?发生了什么事?你的预期产量是多少?请回答您的问题。输入文件正确吗?它有。。。这肯定是无效的。我已经整理了你代码的格式。不客气,但请以后考虑一下。如果您希望大量陌生人阅读和理解您的代码,那么尽可能使其易于理解肯定是有意义的。深思熟虑的格式是程序员使代码易于理解的最佳工具之一。也许你应该仔细阅读并仔细研究它所需要的第三个可选参数。希南在他的回答中利用了它。你的答案是否是开放的。。。{…}故意让人迷惑?标准开放式有什么问题吗。。。或包括原始海报在内的Perl程序员已经使用了几十年了?这不是不喜欢bro,而是建设性的批评。Sinan是一个理解语言并知道如何使用语法的人。很明显,你正在以与原始海报完全相同的方式反对这种语言:-如果你在这样一个网站上发布建议,我始终认为值得付出额外的努力来制作易于理解的代码,以最好的方式展示这种语言。我不确定你是否同意这个目标。看看你的代码。压痕到处都是。您正在加载不使用的模块。您在使用变量的范围之外声明变量。这不仅仅是为了完成工作。它是关于向人们展示最佳实践的。这不是你要做的。严格来说,拆分“”是不必要的,但它可以避免很多麻烦,以防某个地方有一个游离的引导空间。而且,对于可能在Windows和Unixy系统之间移动的数据文件,s/\s+\z//而不是chomp保存了更多令人头痛的问题——当然,除非有一个规范说尾随空格很重要。