Loading ...
Sorry, an error occurred while loading the content.

Re: [PBML] Newbie array question (there must be a better way)

Expand Messages
  • Mike Lewis
    Thanks Guillermo, Dan and Andrew for the replies. Special thanks to Andrew for the very DETAILED suggestions and explanations. This is exactly the sort of
    Message 1 of 5 , Dec 30, 2000
    • 0 Attachment
      Thanks Guillermo, Dan and Andrew for the replies. Special thanks to
      Andrew for the very DETAILED suggestions and explanations. This is
      exactly the sort of thing I was looking for.

      Mike

      Andrew Johnson wrote:

      > Mike wrote:
      > [snip]
      >
      >> My thought was that I would convert $_ to an array by splitting on
      >> spaces, as in:
      >>
      >> @array=split /\s+/, $_;
      >>
      >> Now this works, but makes accessing the data that I want pretty cryptic.
      >> For instance:
      >>
      >> $array[0] = month
      >> $array[1] = day
      >> $array[2] = time
      >> $array[11] = rejected IP address & port
      >> $array[12] = IP address attempted to access & port
      >>
      >> Then, in order to separate out the ports, I would have to do a:
      >>
      >> @portA=split /:/, $array[11];
      >> @portB=split /:/, $array[12];
      >>
      >> Now, my port number would be $portA[1] & $portB[1].
      >>
      >> So, my question is, isn't there an easier, more logical way to extract
      >> just the data from $_ that is desired and leave the rest behind ?
      >>
      >
      >
      > Well, you can slice a list just like you can slice an array, so if
      > you only want to grab a few known positions from a split-list you
      > can do:
      >
      > my @date = (split)[0,1,2];
      >
      > We can grab the ip-stuff in the same way, and also split on : to
      > separate addresses and ports:
      >
      > my @ip_stuff = map{ split /:/ } (split)[11,12];
      >
      > Now we have:
      >
      > $date[0] <-- month $ip_stuff[0] <-- rem address
      > $date[1] <-- day $ip_stuff[1] <-- rem port
      > $date[2] <-- time $ip_stuff[2] <-- loc address
      > $ip_stuff[3] <-- loc port
      >
      > Or, if you want all 7 items in one array:
      >
      > my @data = (split)[0,1,2,11,12];
      > splice @data, 3, 2, map{split/:/} @data[3,4];
      >
      > and now our @data array contains:
      >
      > (month, day, time, rem_add, rem_port, loc_add, loc_port)
      >
      > If you insist on doing it all in one statement, you may use the map
      > and split together and add a test in the map to detect the ip stuff.
      > One way:
      >
      > my @data = map{/^(\d+\.){3}\d+:\d+/?split/:/:$_}(split)[0,1,2,11,12];
      >
      > Of course, we can probably get away a less specific test -- maybe we
      > just test that the number of dots and colons in a field equals 4 (an
      > ip field has 3 dots and a colon):
      >
      > my @data = map{tr/.://==4?split/:/:$_}(split)[0,1,2,11,12];
      >
      > Or, perhaps since a dot only occurs in address:port fields, we
      > could just check for any dot:
      >
      > my @data = map{/\./?split/:/:$_}(split)[0,1,2,11,12];
      >
      > Now, all of these are dependent on field position when split on
      > spaces -- if there might a condition where these positions might
      > change (additional space in one of the fields) then perhaps you'll
      > want to use a regex as Dan Boger suggested. Here is another regex
      > version that makes allowance for cases when the day is a single
      > digit:
      >
      > my @data = /^(\w+)\s+ # month
      > (\d\d?)\s+ # day
      > (\d\d:\d\d:\d\d) # time
      > .*
      > (\d+\.\d+\.\d+\.\d+): # rem address
      > (\d+)\s+ # rem port
      > (\d+\.\d+\.\d+\.\d+): # loc address
      > (\d+) # loc port
      > /x;
      >
      > regards,
      > andrew


      --

      Linux: Because Bill Gates can't keep it up this long
      11:05am up 27 days, 12:14, 6 users, load average: 1.01, 1.05, 1.07
    Your message has been successfully submitted and would be delivered to recipients shortly.