Beefy Boxes and Bandwidth Generously Provided by pair Networks
XP is just a number
 
PerlMonks  

Re: Can PERL know a line without matching?

by da (Friar)
on Jul 27, 2001 at 20:48 UTC ( [id://100368]=note: print w/replies, xml ) Need Help??


in reply to Can PERL know a line without matching?

Please back up a few steps. Can you state what you want your code to do, in ordinary language? You say what your inputs are, what code you tried, but your description of what you want to accomplish is all muddled up with what you tried, and the end product doesn't make much sense, at least to me.

Are you:

  • Trying to compare two files, and if they have an identical line, print the lines from the second file surrounding that line?
  • Searching a number of texts for a particular string from the command line, and if the string appears in one of the texts, print the first line of the text along with the lines surrounding the match?
  • or perhaps something more complicated?

___ -DA > perl -MPOSIX -le '$ENV{TZ}="EST";print ctime(1000000000)' Sat Sep 8 20:46:40 2001

Replies are listed 'Best First'.
Re: Re: Can PERL know a line without matching?
by Anonymous Monk on Jul 28, 2001 at 00:39 UTC
    I'm searching a single text file. If I match on a phone number I want it to print certain lines within the block record that it find it in. The block records have different titles and data in them but always have the phone number. So if I find the phone number and devise a way of recognizing what record block it is then I can tell the script for this record block print these lines and for this record block print these lines only if you find the phone number and recognize the block record heading.

    The Brassmon_k
    The examples above helped me a little but am still not getting correct results. I can't seem to get the script to print off any other even if it matches them except for the line with the phone number in it.
      If I can restate the problem to make sure I understand it:

      You have a text file with records which start with a newline, a line of text, and another newline. You want to print selected lines from a record, if both the following are true: the record title matches a predefined list, and the phone number is in the record. The title of the record determines which lines of the record to print.

      Your question for us is how to find out what record you're looking at.

      It sounds like bikenomad's code should do almost exactly that, if you simply include print statements inside the if statement:

      if ($lastHeading eq 'MEANINGLESS TEXT') { print $lines[2]; # third line print $lines[5]; # sixth line print $lines[7]; # eighth line } elsif ($lastHeading eq 'ALTERNATIVE TEXT') { print $lines[3]; # fourth line print $lines[5]; # sixth line print $lines[7]; # eighth line
      Does this help?

      ___ -DA > perl -MPOSIX -le '$ENV{TZ}="EST";print ctime(1000000000)' Sat Sep 8 20:46:40 2001
        Well I figured it out now with your guys help. It's complete. Well the script isn't but the know-how of it is. I read about $/ and $. and $* in a book but I didn't know how to make them work and I knew that is what I needed. I was lacking the split line with @lines that was my downfall. I didn't know how to tell PERL what the newline was but I see from your entries how to do it. The damn book didn't tell me I needed to do that. Anyway I'll post the script below. It's really rough as of right now because I haven't touched it up that much. It doesn't have warnings on or anything at all but I'll fix that. I was just testing. The tests all came back true. Everything is cool. Here is the script.
        #!/usr/bin/perl chomp($msisdn = <STDIN>); $/ = ""; # read paragraphs $cell = "Cell ID for First Cell: MCC: 310 MNC: 64 LAC: x'44D CI: x' +4F07"; while ($para = <>) { $lastHeading; @lines = split(/\n/, $para); if (@lines == 1) # A Heading { $lastHeading = $lines[0]; next; } if ($lastHeading eq "MSTerminating") { if ($lines[8] =~ m/$msisdn/) { if ($lines[5] =~ m/$cell/) { print "$lastHeading\n"; print "\n"; print "Cell ID for First Cell: MCC: 310 MNC: 64 LAC: x'44D CI: x'MA +D023A\n"; print "$lines[8]\n"; # ninth line print "$lines[4]\n"; # fifth line } } elsif ($lastHeading eq "MSORIGINATING") { if ($lines[7] =~ m/$msisdn/) { print $lines[7]; # eigth line } } elsif ($lastHeading eq "mSOriginatingSMSinSMSIWMSC") { if ($lines[4] =~ m/$msisdn/) { print "$lines[4]\n"; # fifth line } } } }
        Well as you can see I got the script to only print off the lines I wanted when it finds the phone number or $msisdn and the $cell line. Well I have a lot more lines to add that aren't in there but the MSTerminating block should give you the best idea of what I was trying to accomplish and finally did. It works seamlessly right now. PERL can do anything! Here's the reason I wanted to rewrite this into PERL. One for easy maintenance and updates and 2 to rewrite something a former employee wrote that in my opinion being a disliker of AWK is a hideous script.
        Here it is.
        # Asks input for what msisdn (phone number) you are looking for and th +en it appends it's output to a file otherwise it is displayed on scre +en. # The fields, Called, Calling, and Redirecting are fields pulled out o +f the TTFILES # Script modified by David M. Hagens # Original script creator Jeff Toles # Copyright Airadigm Communications #!/usr/bin/sh echo "What msisdn?" read msisdn awk "BEGIN{ msisdn=\"$msisdn\"; }"' { #printf("%s\n", ARGV[2]) line14 =line13 line13 =line12 line12 =line11 line11 =line10 line10 =line9 line9 =line8 line8 =line7 line7 =line6 line6 =line5 line5 =line4 line4 =line3 line3 =line2 line2 =line1 line1 =$0 } /Called/ {if(match($9,msisdn)) a=1;} a>0 {if(a==1&&match(line12,"MSTerm")) {print "\n" line12"\n" line2"\n" +line1;MSTerm=1} if(a==1&&match(line11,"TRANSIT")) {print "\n" line11"\n" line2"\n"line +1; Transit=1} if((a==8||a==9||a==10)&&MSTerm) print $0 if((a==6||a==7||a==8)&&Transit) print $0 if (a++>10) { a=0;MSTerm=0;Transit=0}; } /Calling/ {if(match($9,msisdn)) b=1;} b>0 {if(b==1&&match(line10,"MSORIG")) {print "\n" line10"\n"; MSOrig= +1} if(b==1&&match(line10,"TRANSIT")){print "\n" line10"\n"; Transit=1} if((b<=2||b==5||b==7||b==8)&&MSOrig) print $0 if((b<=2||b==7||b==8||b==9)&&Transit) print $0 if (b++>8) { b=0; MSOrig=0;Transit=0}; } /Redirecting/ {if(match($8,msisdn)) c=1;} c>0 {if(c==1&&match(line14,"CallForward")) print "\n" line14"\n" line5 +"\n" line4"\n" ; if(b<=5) print $0 if (c++>5) { c=0;}; }' output.abbazabba > msisdnoutput.abbazabba; echo "The file with your + search results is called "msisdnoutput.abbazabba""
        I rewrote some of it such as to get it to read STANDARD IN before you had to manually enter the msisdn number by editing the script and inserting the number you wanted in a msisdn variable. Then the output is sent to a file. Otherwise all the AWK syntax is from a former employee. I know what the scripts accomplishing but I'll be damned if I can read AWK or alter this script to get it to do what I want so as much as I hate reinventing the wheel it was for the best. I'll give him this he is good with AWK because that's the only language he uses. I still think it sucked.

        The only downside of this script is I got a list of cell sites (The thing mentioned in $cell = "Blah") and they are to the BASE 10 and they are a separate list that gives the city code of the cell site which is in BASE 16.

        For example: MAD023A 310-64-1101-20231 <--This is the BASE 10 form and is represting our 23rd cell site sector in Madison Wisconsin, It's one of the cell sites a big list of them.
        Cell ID for First Cell: MCC: 310 MNC: 64 LAC: x'44D CI: x'4F07 <--This example is the same exact thing to the BASE 16 which is in the text that I go through.
        So in the end I want it to print --> Cell ID for First Cell: MCC: 310 MNC: 64 LAC: x'44D CI: x'MAD023A' as in the script.

        Now I read in the 3rd Edition Perl Programming that their is a base class/object but it's definition is devoid of any relation to number bases just as HEX isn't mentioned. I'm wondering is their an easy way to just tell PERL the following: If you match x'4F07' on $lines5 of "MSTerminating" :(
        Extreme not smily face because I just realized this is going to have to be a manual process either way I do it. Reason I say that is Bcuz my boss wants it printed out as I have it in the script otherwise I'd just print the appropriate line from the file that contains the city name and BASE 10 code.

        Thanks so much. This is the best PERL FORUM on Earth and on the net. Thanks bikeNomad & thanks DA or Dan
        You guyz are cool.

        I'll check up on this see if you guys throw in any pointers. THANKS!

        The Brassmon_k
        David M. Hagens
        OK that worked for the lines printing. Thank you, I understand it. I just didn't know that PERL would know what lines to print if you split on the newline. I'm very unfamiliar with multi-line as I said. I'm having problems with one last thing though. I'll show you a small portion of the text I'm working with and what I want to do is limit what the script prints. I'm sorry you guys told me exactly what I wanted to know but I started off with a simple explanation, well as easy as I could so I could work on the last part later. I'll show you the text I'm going through then I'll show you how I modified Bike Nomads script with your idea and made it work.
        mSOriginatingSMSinSMSIWMSC Call Identification Number: 10275084 Record Sequence Number: 2205369 Exchange Identity: MAPP01E 0117802 MSC Identification: TON: 1 NPI: 1 MSISDN: 19207079800 Calling Party Number: TON: 1 NPI: 1 MSISDN: 19207029659 Date for Start of Charge: 01/07/18 Time for Start of Charge: 00:14:33 Traffic Activity Code: TeleService Code: x'22 Service Centre Address: TON: 1 NPI: 1 MSISDN: 14147139800 Charged Party: 0 Miscellaneous Information: NULL MSTerminating Call Identification Number: 10275019 Related Call Number: 10275004 Record Sequence Number: 2205370 Exchange Identity: MAPP01E 0117802 MSC Identification: TON: 1 NPI: 1 MSISDN: 19207079800 Cell ID for First Cell: MCC: 310 MNC: 64 LAC: x'44D CI: x'4F07 Incoming Route: MAD01TI Outgoing Route: BAPL01O Calling Party Number: TON: 4 NPI: 1 MSISDN: 6082572086 Called Party Number: TON: 1 NPI: 1 MSISDN: 16084466501 IMSI: 310640010049547 IMEI: NULL Mobile Station Roaming Number: TON: 1 NPI: 1 MSISDN: 16084469974 Redirecting Number: NULL Redirection Counter: 0 Original Called Number: NULL Date for Start of Charge: 01/07/18 Time for Start of Charge: 00:14:33 Chargeable Duration: 00:00:00 Traffic Activity Code: *020 TeleService Code: x'11 Bearer Service Code: NULL Internal Cause and Loc: LOCATION: 2 CAUSE: 61 Time from Register Seizure to Start of Charging: 00:00:18 Time for Stop of Charging: 00:14:33 Interruption Time: 00:00:00 Type of Calling Subscriber: 1 Disconnecting Party: 2 Charged Party: 1 Fault Code: NULL eosInfo: x'0 Call Position: 2 Miscellaneous Information: NULL Restart During Call: NULL Restart Between Disc and Output: NULL Origin for Charging: x'1 Cell ID for Last Cell: MCC: 310 MNC: 64 LAC: x'44D CI: x'4F1D Location Number: TON: 1 NPI: 1 MSISDN: 14147089800 Output for Subscriber: NULL Last Partial Output: NULL Partial Output Rec Num: NULL Regional Service Used: NULL Region Dependent Charging Origin: NULL Transparency Indicator: NULL dTMFUsed: NULL Tariff Class: x'A Tariff Switch Indicator: 0 SS Code: NULL ICI Ordered: NULL
        Now for the script
        #!/usr/bin/perl chomp($msisdn = <STDIN>); $/ = ""; # read paragraphs while ($para = <>) { $lastHeading; @lines = split(/\n/, $para); if (@lines == 1) # A Heading { $lastHeading = $lines[0]; next; } my $hitMe; if ($msisdn && $lastHeading eq "MSTerminating") { #if ($lastHeading eq "MSTerminating") { print $lines[13]; # twelth line print $lines[2]; # third line print $lines[5]; # sixth line print $lines[4]; # fifth line } elsif ($lastHeading eq "MSORIGINATING") { $hitMe = $lines[5]; # sixth line } elsif ($lastHeading eq "mSOriginatingSMSinSMSIWMSC") { print $lines[5]; } }
        As you can see from the script what I'm trying to do is have the Title of the record block and the lines I specifiy per block to print only if the script finds the $msisdn in any of the blocks. That's the phone number or 10th line #11th if you count Title "MSTerminating" as line 1 for a block. At the end the number is 6082572086. So for example since that is the number I'm interested in, the only record block which contains the number I'm searching for is "MSTerminating" and not any of the other record blocks so I'd want it to print off only the lines for "MSTerminating" as that is the only place the number was found.

        I was thinking of doing "if (grep, $msisdn) {" then your if The && operator I used didn't seem to work. The && operator confuses me as to me the logic says if this and that do what I tell you to. It hates me though. I was thinking of doing a couple variations but you guys have helped me with the hardest part in my opinion because I didn't know multi-line. I'll remember what you guys taught me so I'm not back here nagging you guys all the time. I can write regex's to search inside files for single lines and search files in directories and "printem"(Possible new print statement? LOL) or pull them but this was something different and I read the books but half the stuff was reading greek to me cuz I never had to use it. Some of the stuff I think you just gotta use it to understand it.

        Well please offer your advice on the last portion.
        Thankyou lots,
        Dave
      Ok, it is becoming a little more clear.

      You need to keep every line in the block, probably by assigning each line as an element of an array. After you determine that a text block is the one you want, you can print each line you want from the array, or all of them. How you decide to print a given line could be done with a regex or grep or other possiblities. If you can't get it to work now, post some code, and we'll give you pointers.

      Scott

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others goofing around in the Monastery: (2)
As of 2024-04-25 06:05 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found