Bladernr has asked for the wisdom of the Perl Monks concerning the following question:

Okie... I know this is pretty boneheaded, but I am not entirely fluent in perl, and am at the point where I know just enought to be dangerous. <grin>

Heres what I need help on:

given a file called foo.log with lines of text that look like this:
Sep 15 14:18:54 203.146.91.228:23 202.88.143.72:23

I wanted to be able to strip that seconds field from the timestamp, so that 14:18:54 would become 14:18

so far, I have gotten an array of the items in each line, and from that array, created various scalars based on what the object is... i.e. month, day, time, data1, and data2

here is the code sofar:

##!/usr/bin/perl # #my @lines; #@lines=`cat foobar`; # #foreach (@lines) { # # my($month, $day, $time, $data1, $data2) = split / /; # open(NEWTIME, $time); # while (<NEWTIME>) { # my($hour, $minute, $second) = split /:/; # $time2 = join(':', $hour, $minute); # } # select NEWLOG; # print "$time2\n"; #open NEWLOG, ">>foofinal.txt"; #}


of course ignore the hashmarks...

Now, after testing each variable, they are all assigned as they should be...except for @time2. I cant get $time2 to reflect the result of the join statement, and then print it out to the final txt file.

The goal is to have $time2 be the HH:MM time format, and reinsert that into the logfile so that in the final file the lines would look like this:

Sep 15 14:18 203.146.91.228:23 202.88.143.72:23

I know I have probably made many errors, so please show me the light!

Oh, and I did originaly have use strict in the beginning, however, that continuously gave me errors with $time2 and removing the 'use strict' line cleared those errors (of course) and allowed the script to complete. However at teh end of each run with the time variable, $time2 is always printed as a " " instead of a join between $hour and $minute.

Thanks
Jeff

Replies are listed 'Best First'.
Re: get my variable out of the hole!
by davorg (Chancellor) on Sep 18, 2002 at 09:22 UTC

    you've had a few suggestions on way to rewrite your code, but it might be useful to have a quick look at what you were doing wrong.

    foreach (@lines) { my($month, $day, $time, $data1, $data2) = split / /; open(NEWTIME, $time);

    Here you've tried to open a file which has the name $time. I strongly suspect that this file doesn't exist. Checking the return value from open would have told you this.

    while (<NEWTIME>) {

    Having opened a file that doesn't exist, you proceed to try and read from it. If you had use warnings turned on, you would have been warned at this point. However, as the file doesn't exist is is effectively empty and <NEWTIME> won't return any data so the code in the while loop never gets executed.

    my($hour, $minute, $second) = split /:/; $time2 = join(':', $hour, $minute); }

    As I said above, this code is never executed - which is why $time2 never gets set.

    select NEWLOG; print "$time2\n";

    It looks like you're selecting a filehandle that hasn't been opened.

    open NEWLOG, ">>foofinal.txt"; }

    Once more, you should check the return code from open.

    --
    <http://www.dave.org.uk>

    "The first rule of Perl club is you do not talk about Perl club."
    -- Chip Salzenberg

      you've had a few suggestions on way to rewrite your code, but it might be useful to have a quick look at what you were doing wrong.

      Yep... actually, that would be quite useful... I am still learining the ways, and doing it slowly unfortunately, as the need to pay the bills is overriding the desire to learn new skills... sigh... I miss my old job. ;)

      foreach (@lines) { my($month, $day, $time, $data1, $data2) = split / /; open(NEWTIME, $time);

      Here you've tried to open a file which has the name $time. I strongly suspect that this file doesn't exist. Checking the return value from open would have told you this.

      Ahhh... the idea was (misguided to say the least) an attempt to open a filehandle using the contents of $time. obviously that was wrong...

      while (<NEWTIME>) {

      Having opened a file that doesn't exist, you proceed to try and read from it. If you had use warnings turned on, you would have been warned at this point. However, as the file doesn't exist is is effectively empty and <NEWTIME> won't return any data so the code in the while loop never gets executed.

      Yes... sigh... I know better than that as well... I should always have the -w switch on, but for somereason it completely slipped me when I started this lil project.

      select NEWLOG; print "$time2\n";

      It looks like you're selecting a filehandle that hasn't been opened.
      open NEWLOG, ">>foofinal.txt"; }
      Once more, you should check the return code from open.

      I dont remember why it is I had the open after the select statement... I borrowed this code from another script I had been working on months ago and had stopped working on for one reason or another... at that point, I was trying to get my way through the Llama book during my lunch breaks at work, while also trying to do some "real world" problems to help learn more...

      Thank you tho for the guidance on what was happening. As stated earlier, I am still much a beginner, and have MUCH left to learn. And this is all much more difficult to do when you have had no formal or even informal training, and all the training you do have is garnered a few minutes here, and a few minutes there... hehe... I feel kinda silly now...

      and to be honest, this all started because I cant find my sed/awk pocket ref, so I figured it would be fun to try to do it in perl instead... heheeh... Now I have the answer in both perl and bash.

      Thanks again!
Re: get my variable out of the hole!
by dws (Chancellor) on Sep 18, 2002 at 08:29 UTC
    I wanted to be able to strip that seconds field from the timestamp, so that 14:18:54 would become 14:18

    If your input lines look like   Sep 15 14:18:54 203.146.91.228:23 202.88.143.72:23 Then a regular expression like   s/^(\w{3}\s+\d+\s+\d+:\d+):\d+(.*$)/$1$2/; should strip off seconds. No need to split() the line into tokens to process it.

Re: get my variable out of the hole!
by davorg (Chancellor) on Sep 18, 2002 at 08:31 UTC
    perl -pe 's/:\d\d(?=\s)//' < infile > outfile
    --
    <http://www.dave.org.uk>

    "The first rule of Perl club is you do not talk about Perl club."
    -- Chip Salzenberg

Re: get my variable out of the hole!
by AcidHawk (Vicar) on Sep 18, 2002 at 08:35 UTC
    $time2 = join(':', $hour, $minute);

    Have you tried to just use

    $time2 = "$hour:$minute";

    -----
    Of all the things I've lost in my life, its my mind I miss the most.