Beefy Boxes and Bandwidth Generously Provided by pair Networks
Welcome to the Monastery
 
PerlMonks  

creating a hash from a text file.

by changma_ha (Sexton)
on Jul 27, 2010 at 06:51 UTC ( #851475=perlquestion: print w/replies, xml ) Need Help??

changma_ha has asked for the wisdom of the Perl Monks concerning the following question:

i know it this question seem to be silly but i am struck here. i have a text file like

1 human 2 flower 3 fruits 5 human 6 car 9 flower asdgjhashdnh gsdh sjs klja

now i want my output to be like 1= human 2= flower 3 =fruits 5 =human 6= car 9= flower

my code is :

#!/usr/bin/perl #use strict; #use warnings; my %hash; open (my $fh,"<", "c:/asso2.txt") or die "Can't open the file: "; while (my $line =<$fh>){ chomp ($line); if ($line =~ /\d\s+\w/){ my ($index, $data)=split (/\s+/,$line); #split on the basis + of space $hash{$index} =$data; #Assign the value to key } } foreach my $i(sort keys %hash){ print "$i =$hash{$index}\n"; }

plz give me wiser . what can be the mistake

Replies are listed 'Best First'.
Re: creating a hash from a text file.
by moritz (Cardinal) on Jul 27, 2010 at 07:06 UTC
    Your data file seems to contain several items per line, but you're only looking for one. Maybe try
    while ($line =~ /(\d+)\s+(\w+)/g) { $hash{$1} = $2; }

    In your inner loop.

    Update: added /g, as noted by AnomalousMonk.

    Perl 6 - links to (nearly) everything that is Perl 6.

      Loop condition
          while ($line =~ /(\d+)\s+(\w+)/) { ... }
      will produce infinite loop. Use /g regex modifier to extract all pairs:
          while ($line =~ /(\d+)\s+(\w+)/g) { ... }

Re: creating a hash from a text file.
by AnomalousMonk (Bishop) on Jul 27, 2010 at 07:11 UTC

    Assuming you want to ignore the 'asdgjhashdnh gsdh sjs klja' stuff and only extract single-digit/alpha-string pairs, this might be a way to go (sorry for the wrap-around):

    >perl -wMstrict -le "my $s = '1 human 2 flower 3 fruits 5 human 6 car 9 flower asdgjhashdn +h gsdh sjs klja'; my %hash = $s =~ m{ (\d) \s+ ([[:alpha:]]+) }xmsg; use Data::Dumper; print Dumper \%hash; " $VAR1 = { '6' => 'car', '1' => 'human', '3' => 'fruits', '9' => 'flower', '2' => 'flower', '5' => 'human' };

    One problem with
        my ($index, $data)=split (/\s+/,$line);
    is that it only captures the first index/data pair, and the example in the OP has several pairs per line. (Update: This is actually pointed out by moritz.) Another problem is that the extraneous data (the 'asdgjhashdnh gsdh sjs klja' stuff) would not be filtered out by a split that simply captured all the field pairs generated.

Re: creating a hash from a text file.
by johngg (Canon) on Jul 27, 2010 at 10:52 UTC

    You can avoid global regex matches if you split into key/value pairs then further split on spaces slicing out the first two elements.

    $ perl -MData::Dumper -e ' > my $str = q{1 human 2 flower 3 fruits 5 human 6 car 9 flower asdgjha +shdnh gsdh sjs klja}; > my %hash = > map { ( split m{\s+} )[ 0, 1 ] } > split m{(?x) (?<=\w) \s+ (?=\d)}, $str; > print Data::Dumper->Dumpxs( [ \ %hash ], [ qw{ hash } ] );' $hash = { '6' => 'car', '1' => 'human', '3' => 'fruits', '9' => 'flower', '2' => 'flower', '5' => 'human' }; $

    I hope this is of interest.

    Cheers,

    JohnGG

      Why would one want to bother avoiding global regex matches? (In fact, doesn't split at some level involve a global regex match?)

        Poor wording on my part! What I meant was "as an alternative to" but it came out wrong :-(

        Cheers,

        JohnGG

Re: creating a hash from a text file.
by Generoso (Prior) on Jul 27, 2010 at 15:19 UTC

    Try this see if it helps.

    #!/usr/bin/perl -w # gene.plx # use strict; my %hash = (); while (<DATA>) { chomp($_); my ($dept,$email)=split(/:/); $hash{ $dept } .= $email.','; } s/,\z// for values %hash; print "\n"; while ( my ($key, $value) = each(%hash) ) { print "$key => $value\n"; } print "size of hash: " . keys( %hash ) . ".\n"; print '-' x (60),"\n"; __DATA__ 6:car 1:human 3:fruits 9:flower 2:flower 5:human

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://851475]
Approved by Corion
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others lurking in the Monastery: (3)
As of 2022-09-28 09:08 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    I prefer my indexes to start at:




    Results (124 votes). Check out past polls.

    Notices?