Beefy Boxes and Bandwidth Generously Provided by pair Networks
Don't ask to ask, just ask
 
PerlMonks  

File Reading

by mantra2006 (Hermit)
on Oct 01, 2007 at 12:54 UTC ( #641872=perlquestion: print w/replies, xml ) Need Help??

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

Hello Monks
I need your ideas in tackling this problem with perl. The following is the requirement
consider a file with the following format: a header row with colon-se +parated field names, and data rows with colon-separated values. for example: AGE:EYES:HAIR 32:BLUE:BLONDE 54:BROWN:BROWN Now from the command line if I pass AGE as parameter then it should gi +ve me 32 & 54...if I pass HAIR then it should give me BLONDE & BROWN. +...
Any ideas how to tackle this problem is welcome....thanks in advance for the help...

Thanks & Regards
Sridhar "Coming together is a beginning. Keeping together is progress. Working together is success.- Henry Ford

Replies are listed 'Best First'.
Re: File Reading
by andreas1234567 (Vicar) on Oct 01, 2007 at 13:19 UTC
    Any ideas how to tackle this problem is welcome
    Create a hash of arrays, where the hash keys are the elements one the first line, and the array elements are values from each column respectively. Read perldata, perlfaq4.
    $ perl -w 641872.pl $VAR1 = { 'EYES' => [ 'BLUE', 'BROWN' ], 'AGE' => [ '32', '54' ], 'HAIR' => [ 'BLONDE', 'BROWN' ] };
    Update: The implementation is intentionally excluded since this is an obvious homework question. Memory concerns are considered out of scope. In real life I would probably use cut (Unix).
    --
    Andreas
      Hi,
      ++andreas1234567, yes, that will work, but you will always fill your memory with a lot of unnecessary data before you actually output any data.
      Without saying too much (to not make the OP's homework too easy ;-)), I'd first find out which column is actually searched for, then go through the rest of the file line by line and print the only column that is requested.
      No building up of a huge hash...
      Regards,
      svenXY
Re: File Reading
by Skeeve (Parson) on Oct 01, 2007 at 13:04 UTC
    Nice try getting your homework solved... Show us what you already have done...

    s$$([},&%#}/&/]+}%&{})*;#$&&s&&$^X.($'^"%]=\&(|?*{%
    +.+=%;.#_}\&"^"-+%*).}%:##%}={~=~:.")&e&&s""`$''`"e
Re: File Reading
by Limbic~Region (Chancellor) on Oct 01, 2007 at 14:36 UTC
    mantra2006,
    I agree with others, this looks like homework. After reading a few of the 70+ other posts you have made over the last year, I am willing to give you the benefit of a doubt.
    #!/usr/bin/perl use strict; use warnings; my $file = $ARGV[0] or die "Usage: $0 <input_file>"; open(my $fh, '<', $file) or die "Unable to open '$file' for reading: $ +!"; my $header = <$file>; chomp $header; my @field = split /:/, $header; print "What field would you like to look for?\n"; my $choice = <STDIN>; chomp $choice; while (<$fh>) { chomp; my %record; @record{@field} = split /:/; print "$record{$choice}\n"; }
    It is untested and intentionally does not do a lot of the error checking that it should. These are tasks that you will need to do yourself.

    Cheers - L~R

Re: File Reading
by jwkrahn (Monsignor) on Oct 01, 2007 at 13:43 UTC
    $ echo "AGE:EYES:HAIR 32:BLUE:BLONDE 54:BROWN:BROWN" | \ perl -F: -lane' BEGIN { $key = uc shift } if ( $. == 1 ) { @x{ map uc, @F } = 0 .. $#F } else { print $F[ $x{ $key } ] } ' age 32 54 $ echo "AGE:EYES:HAIR 32:BLUE:BLONDE 54:BROWN:BROWN" | \ perl -F: -lane' BEGIN { $key = uc shift } if ( $. == 1 ) { @x{ map uc, @F } = 0 .. $#F } else { print $F[ $x{ $key } ] } ' eyes BLUE BROWN $ echo "AGE:EYES:HAIR 32:BLUE:BLONDE 54:BROWN:BROWN" | \ perl -F: -lane' BEGIN { $key = uc shift } if ( $. == 1 ) { @x{ map uc, @F } = 0 .. $#F } else { print $F[ $x{ $key } ] } ' hair BLONDE BROWN
      Hi,
      ++jwkrahn for reminding me of the precious $.!
      Regards,
      svenXY
Re: File Reading
by zer (Deacon) on Oct 01, 2007 at 13:12 UTC
    yes i concur. Either way this looks like it is better done with a shell script than perl just from the sounds of it. (this is where i get a ton of --'s)
Re: File Reading
by ambrus (Abbot) on Oct 02, 2007 at 07:30 UTC

    I recommend the $_ = <>; @f = split; while (<>) { @a{@f}= split; print $a{$field}; } trick from Re: updating Input file.

Re: File Reading
by dwm042 (Priest) on Oct 01, 2007 at 14:57 UTC
    This is a coded solution to the issue, a mostly plain one.

    #!/usr/bin/perl use warnings; use strict; my $tag = shift; die ("You need to enter a tag.\n") unless ( $tag =~ /\w+/ ); my $count = 0; my @headers = (); my %hash = (); while(my $d = <DATA>) { $count++; chomp ($d); if ( $count < 2 ) { @headers = split/:/, $d; } else { my @temp = split/:/, $d; push @{$hash{$headers[$_]}}, $temp[$_] for ( 0 .. $#headers ); + } } if ( defined($hash{$tag}) ) { print "$tag = ",join( ',', @{$hash{$tag}} ), "\n"; } else { print "Tag $tag not found.\n"; } __DATA__ AGE:EYES:HAIR 32:BLUE:BLONDE 54:BROWN:BROWN
    And the results are:

    C:\Code>perl show_tags.pl foo Tag foo not found. C:\Code>perl show_tags.pl AGE AGE = 32,54 C:\Code>perl show_tags.pl EYES EYES = BLUE,BROWN
Re: File Reading
by aquarium (Curate) on Oct 01, 2007 at 15:20 UTC
    excuse the political incorrectness.....is this the entrance question for a job as a perl programmer in an indian call centre?....because then the output should actually be
    32:blue:blonde --> gullible target?
    54:brown:brown --> not a threat to the blonde
    only kidding folks
    i think homework should receive obfuscated code...if any, as no attempt was made
    the hardest line to type correctly is: stty erase ^H
      aquarium was closest. mantra2006 was trying to get a job.

      he was unsuccessful.

        So now as he was unseccessfull, I'd like to get the job ;-)

        Here is my solution, lacking any kind of error checking of course...

        #!/usr/bin/perl use strict; use warnings; # read headline $_= <DATA>; chomp; # split into words my @headline= split /:/; # assign each word a column number my %headline; @headline{@headline}= (0..$#headline); # get the required columns my @columns= @headline{@ARGV}; # print the column headers print join(':',@ARGV),"\n"; # read each line while (<DATA>) { chomp; # and print what's requested print join(':',(split /:/)[@columns]),"\n"; } __DATA__ AGE:EYES:HAIR 32:BLUE:BLONDE 54:BROWN:BROWN

        s$$([},&%#}/&/]+}%&{})*;#$&&s&&$^X.($'^"%]=\&(|?*{%
        +.+=%;.#_}\&"^"-+%*).}%:##%}={~=~:.")&e&&s""`$''`"e

Log In?
Username:
Password:

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

How do I use this? | Other CB clients
Other Users?
Others having an uproarious good time at the Monastery: (1)
As of 2022-10-04 00:35 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    My preferred way to holiday/vacation is:











    Results (15 votes). Check out past polls.

    Notices?