in reply to multiple values per key

Almost right. You are missing a $ off of data1 in the push. It should be:

push ( @{$data1{$call1}}, $sipm );

and your print would be better as:

print "@{$data1{$call1}}\n";

which interpolates the array elements into the string. With both changes your code prints:

100 200 180 200 200 183 180 100 503 503 503

DWIM is Perl's answer to Gödel

Replies are listed 'Best First'.
Re^2: multiple values per key
by convenientstore (Pilgrim) on Jul 20, 2007 at 13:22 UTC
    beautiful. thank you so much
      Now, below program works.. but I still see some uninitialized values
      Here's what I mean. I am running a below code against file that has SIP message, which has various format according to what message and what situation. When I run below code against entire file, it works but exception of some areas where I don't get my value initialized and I suspect that when it goes through line (14-16), it doesn't find the match? and it skips out as I see error message
      Use of uninitialized value at ./perl.m line 32, <FH> chunk 1. Use of uninitialized value at ./perl.m line 32, <FH> chunk 1. Use of uninitialized value at ./perl.m line 32, <FH> chunk 894. Use of uninitialized value at ./perl.m line 32, <FH> chunk 896. Use of uninitialized value at ./perl.m line 32, <FH> chunk 898.
      but line 17 through 38, it recognize as entire record and process what it needs to.. What am I missing in line 14 through 16 that my regular expression is not matching(I want it to match so that it skips out(next record).
      #!/usr/bin/perl -w use strict; my $ncb = $/; my $cbn = $"; $/ = "\n\n"; $" = "\n"; open FH, 'file1' or die "can't open file $!"; my $callid; my $sipm; my %data1 = (); while (<FH>) { chomp; if (m/^###|^\s*$/s) { next ; } m{(^SIP\/2\.0 \d\d\d|^[A-Z]{3,6} ).*(Call-ID: [\S]{25,80})[^ ]+: .*}s; ($sipm,$callid) = ($1,$2); #print "\$sipm is $sipm and \$callid is $callid\n"; push (@{$data1{$callid}}, $sipm); } $/ = $ncb; $" = $cbn; foreach $callid (sort keys %data1) { print "$callid \n", " @{$data1{$callid}}\n"; } close FH;
      top portion of file1 with line number printed out for identification
      14 $ 15 ### sendto xxx.xxx.xxx.xxx7:5060 679 bytes @ Wed Feb 7 14:22: +22 2007$ 16 $ 17 SIP/2.0 200 OK^M$ 18 Via: SIP/2.0/UDP xxx.xxx.xxx.xxx7:5060;branch=xxxxxxxxxxxxxxxx +xxxxxxx;received=xxx.xxx.xxx.xxx7^M$ 19 From: sip:1223456679@xxx.xxx.xxx.xxx7;tag=xxxxxxxxx--116851850 +4^M$ 20 To: sip:18000003333@xxx.xxx.xxx.xxx;tag=ccid-306500088-1-2020^ +M$ 21 Allow: ACK,BYE,CANCEL,INVITE,OPTIONS^M$ 22 Call-ID: Something--662631336@xxx.xxx.xxx.xxx7^M$ 23 CSeq: 1 INVITE^M$ 24 Contact: <sip:xxx.xxx.xxx.xxx:5130>^M$ 25 26 Content-Length: 201^M$ 27 Content-Type: application/sdp^M$ 28 ^M$ 29 v=0^M$ 30 o=50053 306500088 306500088 IN IP4 xx.xx.xx.xx^M$ 31 s=SIP Call^M$ 32 c=IN IP4 xx.xx.xx.xx^M$ 33 t=0 0^M$ 34 m=audio 53776 RTP/AVP 0 11^M$ 35 a=rtpmap:0 PCMU/8000^M$ 36 a=rtpmap:101 telephone-event/8000^M$ 37 a=fmtp:101 0-11^M$ 38 $
        if (m/^###|^\s*$/s) {

        should be:

        if (m/^###|^\s*\$/s) {

        You need to quote $ because it's the "end of line" match meta character.

        It would help to diagnose such problems if you tested your subsequent match and print a diagnostic if it fails:

        unless (m{(^SIP\/2\.0 \d\d\d|^[A-Z]{3,6} ).*(Call-ID: [\S]{25,80}) +[^ ]+: .*}s) { print "No match: $_\n"; next; }

        DWIM is Perl's answer to Gödel
        I continue with this code and still trying to understand why my hash works but still get piles of warning saying
        Use of uninitialized value at ./perl.m line 24, <FH> chunk 894. Use of uninitialized value at ./perl.m line 24, <FH> chunk 894. Use of uninitialized value at ./perl.m line 24, <FH> chunk 896. Use of uninitialized value at ./perl.m line 24, <FH> chunk 898. Use of uninitialized value at ./perl.m line 24, <FH> chunk 900. Use of uninitialized value at ./perl.m line 24, <FH> chunk 902. Use of uninitialized value at ./perl.m line 24, <FH> chunk 904. Use of uninitialized value at ./perl.m line 24, <FH> chunk 906. Use of uninitialized value at ./perl.m line 24, <FH> chunk 922. Use of uninitialized value at ./perl.m line 24, <FH> chunk 924. Use of uninitialized value at ./perl.m line 24, <FH> chunk 926. Use of uninitialized value at ./perl.m line 24, <FH> chunk 928. Use of uninitialized value at ./perl.m line 24, <FH> chunk 930. Use of uninitialized value at ./perl.m line 24, <FH> chunk 932. Use of uninitialized value at ./perl.m line 24, <FH> chunk 934. Use of uninitialized value at ./perl.m line 24, <FH> chunk 936. Use of uninitialized value at ./perl.m line 24, <FH> chunk 938. Use of uninitialized value at ./perl.m line 24, <FH> chunk 940. Use of uninitialized value at ./perl.m line 24, <FH> chunk 942. Use of uninitialized value at ./perl.m line 24, <FH> chunk 944. Use of uninitialized value at ./perl.m line 24, <FH> chunk 946.
        Also, I try to debug this program, and I see that push happens twice(?) in one record. Why? There shoud be only one $callid and $sipm per record.
        main::(perl.m:6): my $cbn = $"; DB<2> main::(perl.m:8): $/ = "\n\n"; DB<2> main::(perl.m:9): $" = "\n"; DB<2> main::(perl.m:11): open FH, 'file1' or die "can't open file $!"; DB<2> main::(perl.m:13): my $callid; DB<2> main::(perl.m:14): my $sipm; DB<2> main::(perl.m:15): my %data1 = (); DB<2> main::(perl.m:17): while (<FH>) { DB<2> main::(perl.m:18): chomp; DB<2> main::(perl.m:19): if (m/###|^$/) { DB<2> main::(perl.m:20): next; DB<2> main::(perl.m:18): chomp; DB<2> main::(perl.m:19): if (m/###|^$/) { DB<2> main::(perl.m:22): m{(?:^SIP\/2\.0 )?(\d\d\d|^[A-Z]{3,6} ). +*(Call-ID: [\S]{25,80})[^ ]+: .*}s; DB<2> main::(perl.m:23): ($sipm,$callid) = ($1,$2); DB<2> main::(perl.m:24): push (@{$data1{$callid}}, $sipm); DB<2> main::(perl.m:24): push (@{$data1{$callid}}, $sipm); DB<2> main::(perl.m:17): while (<FH>) { DB<2> main::(perl.m:18): chomp; DB<2> main::(perl.m:19): if (m/###|^$/) { DB<2> main::(perl.m:20): next; DB<2> main::(perl.m:18): chomp; DB<2> main::(perl.m:19): if (m/###|^$/) { DB<2> main::(perl.m:22): m{(?:^SIP\/2\.0 )?(\d\d\d|^[A-Z]{3,6} ). +*(Call-ID: [\S]{25,80})[^ ]+: .*}s; DB<2> main::(perl.m:23): ($sipm,$callid) = ($1,$2); DB<2> main::(perl.m:24): push (@{$data1{$callid}}, $sipm); DB<2> main::(perl.m:24): push (@{$data1{$callid}}, $sipm); DB<2> main::(perl.m:17): while (<FH>) {
        One more question, why can't I do this??
        38 foreach $callid (sort keys %data1) { 39 # print " @{$data1{$callid}}\n"; 40 my $fields = join (/\s*/, @{$data1{$callid}}); 41 print "$fields\n"; 42 } 43 close FH;
        With print statement alone(which is commented out), it works as designed(with next two lines commented out)
        ~/script/perl/temp@myserver1 >./program file1 There were 0 which could not detect INVITE 100 180 200 ACK BYE 200 INVITE 100 180 200 180 200 ACK BYE 200
        but when I run as above (with print statement # out with next two open with join), I get below
        There were 0 which could not detect Use of uninitialized value at ./perl.m2 line 40, <FH> chunk 32. INVITE 1100118012001ACK 1BYE 1200 Use of uninitialized value at ./perl.m2 line 40, <FH> chunk 32. INVITE 110011801200 Use of uninitialized value at ./perl.m2 line 40, <FH> chunk 32. 18012001ACK 1BYE 1200