in reply to Re^2: multiple values per key
in thread multiple values per key

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 $

Replies are listed 'Best First'.
Re^4: multiple values per key
by GrandFather (Saint) on Jul 22, 2007 at 23:53 UTC
    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
      thanks. that certainly is better alternative.. I just need to now figure out why tiny portion is no match.. everything else runs fine.. and does its job
Re^4: multiple values per key
by convenientstore (Pilgrim) on Jul 22, 2007 at 23:18 UTC
    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>) {
Re^4: multiple values per key
by convenientstore (Pilgrim) on Jul 24, 2007 at 02:39 UTC
    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

      Read the join docs.


      DWIM is Perl's answer to Gödel
        I still do not get it, @{$data1{$callid}} contains something like
        INVITE 100 180 200 INVITE 503 ACK
        so when I do below I expected results to be
        INVITE100180200
        INVITE503ACK
        But instead I get scalar values in return.. why??
        foreach $callid (sort keys %data1) { my @fields = join('', split(/[ +\t]/, @{$data1{$callid}})); print "@fields\n"; }