Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Rookie in Perl, Parsing question 1

Status
Not open for further replies.

logic4fun

Programmer
Apr 24, 2003
85
US
All,
I am trying to do the following in a simple perl script. But as i am very basic to perl i am having tough time getting through.

sample Input files
-----------------
Hello i am fine
JOE::1:122,2:2,3:18,4:37,
i am doing great here
JOE::2:11,3:3,4:3,5:28,6:2
JOE::1:1234,5:12
----------

All i need to do is this
Open a File X
Grep for JOE
And get the total count by respective identifiers. in the above case identifiers are 1,2,3,4,5,6 and the individual counts are the numbers beside them

the final result for the above case should be
1:1356,2:13,3:21,4:40,5:40,6:2


Thanks for any help

logic4fun
{
 
Why don't you post what you have so far, so we can have a look at it.
 
#!/usr/local/bin/perl

use English;
use POSIX;

#creates var $infile
$infile = $ARGV[0];

#if $infile is empty exit
if ($infile eq '') { usage(); exit;};

open(IN,"/bin/grep JOE $file |");

while(<IN>){
@elements = split(/\s+/);
$element_count = @elements;
print "@elements.$element_count \n";
}

sub usage {
die "Try ",__FILE__," FILENAME \n";
}


I Know it is very basic. But i am also very new to perl
 
Code:
#if $infile is empty exit
if ($infile eq '') { usage(); exit;};
This doesn't test if file is empty. It tests whether filename is an empty string.

Why split on whitespace (\s+)? There's no whitespace in the lines you're interested in, per your sample input.

Hints:
0. You should be using strict and warnings. (Much more important than English and POSIX.)
1. Use a hash to hold your output.
2. Split on the double colon (::) to separate the identifier from the data.
3. Split the data on commas to get a list of colon-separated key/value pairs.
4. Split the key/value pairs on a single colon (:) to get each key and value.
5. Add the value to the hash element given by the key.

HTH

 
[tt]ruby -n sums.rb data[/tt]
Code:
BEGIN { $h=Hash.new(0) }
next if $_ !~ /^JOE/
$_.scan(/(\d+):(\d+)/){|x| $h[x[0].to_i]+=x[1].to_i}
END { puts $h.sort.map{|x| x.join(':')}.join(',') }
 
cntr, it says you're an instructor? If you were teaching a perl class (or replying to posts in a perl forum), and someone had a question, would you explain to them how it works in ruby? It seems to me that's like someone asking a question in an English class and you trying to explain it to them in French - it's probably not going to fly.

If someone says they're new to perl and have questions, why would you post a solution in ruby? Why add more confusion?

Anyway, here's an example of splitting up the lines and getting a count. This will need to be modified to open/close a file.
Code:
use strict;
use warnings;

my %count;
while (<DATA>) {
    if (/JOE/) {
        chomp;
        my ($id, $data) = split('::', $_);
        my @pairs = split(',', $data);
        foreach my $pair (@pairs) {
            my ($key, $value) = split (':', $pair);
            $count{$key} += $value;
        }
    }
}

my @output = map { join(':', $_, $count{$_}) } keys %count;
print join(',', @output);

__DATA__
Hello i am fine
JOE::1:122,2:2,3:18,4:37,
i am doing great here
JOE::2:11,3:3,4:3,5:28,6:2
JOE::1:1234,5:12
 
He can simply ignore me if he likes.
[tt]
# Create a hash whose elements have a default value
# of 0.
BEGIN { $h=Hash.new(0) }
# If the line just read, $_, doesn't begin with
# "JOE", skip it.
next if $_ !~ /^JOE/
# Each iteration of scan produces an array like this:
# [n1,n2]; n1 is the number before the colon; n2,
# the number after the colon.
$_.scan(/(\d+):(\d+)/){|x| $h[x[0].to_i]+=x[1].to_i}
# To format hash for printing, first sort, then join
# each key=>value with ":", then join with ",".
END { puts $h.sort.map{|x| x.join(':')}.join(',') }
[/tt]
 
Thanks a lot guys for all your help. it worked fine.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top