String manipulation for a date

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • joeferns79
    New Member
    • Sep 2008
    • 37

    String manipulation for a date

    A file contains the following contents ...

    Code:
    20090224T105933 s990atap01      Statistics      0       curam.util.internal.workflow.intf.WorkflowQueueHandler.handleWorkflow
    EnactmentMessage ( java.lang.String java.lang.String java.lang.Long )   true    5608
    20090224T105940 s990atap01      Statistics      0       curam.util.internal.workflow.intf.WorkflowActivityQueueHandler.handle
    ActivityMessage ( java.lang.String java.lang.Long java.lang.Long java.lang.Long java.lang.String )      true    7308
    I want to replace the date/time string with the following....

    2009-02-24-10.59.33.000000 ......
    2009-02-24-10.59.40.000000 .....

    Of course, this has to repeat for the complete file.

    Is there a Perl command that would do it?
  • KevinADC
    Recognized Expert Specialist
    • Jan 2007
    • 4092

    #2
    There is no perl command to do that but you could use a regexp to capture the date part of the string/line (or maybe another way depending on how the actual data is) and use unpack (or a regexp) and sprintf to reformat it like you want.

    Comment

    • joeferns79
      New Member
      • Sep 2008
      • 37

      #3
      What would the regular expression look like?

      Comment

      • KevinADC
        Recognized Expert Specialist
        • Jan 2007
        • 4092

        #4
        Originally posted by joeferns79
        What would the regular expression look like?
        probably something like:

        Code:
        /searchpattern/

        Comment

        • joeferns79
          New Member
          • Sep 2008
          • 37

          #5
          Man, you truly are an Expert, aren't you? :-)

          Comment

          • KevinADC
            Recognized Expert Specialist
            • Jan 2007
            • 4092

            #6
            My wife always says I am. My kids are generally less complimentary though.

            Comment

            • joeferns79
              New Member
              • Sep 2008
              • 37

              #7
              Kevin,

              I got the following code for this ...

              Code:
              #!/usr/bin/perl
              
              $mystring = "20090216T131131";
              print "The input is $mystring";
              printf "\n";
              @myarray = ($mystring =~ m/(\d+)/g);
              $result = join("", @myarray);
              my ($y,$m,$d,$h,$min,$sec) = unpack("A4A2A2Z2Z2Z2",$result);
              $done = sprintf ("%d-%2.2d-%d-%d.%d.%d.%06s",$y,$m,$d,$h,$min,$sec,0);
              print "$done";
              printf "\n";
              which returns the following ...

              Code:
              bash-3.00$ ./test.pl
              
              The input is 20090216T131131
              2009-02-16-13.11.31.000000
              The problem is i've got a file that contains a number of occurrences of the timestamp, eg
              Code:
              20090224T105710 fem.facade.intf.caseSearch
              20090224T105710 codetable.intf.CodeTable
              20090224T105719 intf.FieldLevelSecurityRuntime
              20090224T105723 resolveCase
              20090224T105724 FieldLevelSecurity
              If I need to use the code above to change all the occurences of a timestamp, one at a time, to the format specified, and feed those back into the file, how should I go about it?

              i.e. I want to change 20090224T105710 to 2009-02-24-10.57.10.000000 ,
              20090224T105719 to 2009-02-24-10.57.19.000000 , and so on.
              Last edited by numberwhun; Aug 22 '09, 01:05 PM. Reason: Please use square brackets for code tags, not angle brackets

              Comment

              • KevinADC
                Recognized Expert Specialist
                • Jan 2007
                • 4092

                #8
                Code:
                open(my $data, "<", "path/to/your/file") or die "$!"; 
                while(my $mystring = <$data>){
                   print "The input is $mystring";
                   my ($date, $otherstuff) = split(/\s+/,$mystring);
                   my ($y,$m,$d,$h,$min,$sec) = unpack("A4A2A2Z2Z2Z2",$date);
                   my $done = sprintf ("%d-%2.2d-%d-%d.%d.%d.%06s",$y,$m,$d,$h,$min,$sec,0);
                   print "$done\n";
                }
                close $data;

                Comment

                • numberwhun
                  Recognized Expert Moderator Specialist
                  • May 2007
                  • 3467

                  #9
                  Please use square brackets for code tags instead of angle brackets and you will get the desired effect that we require. Thanks!

                  Regards,

                  Jeff

                  Comment

                  • joeferns79
                    New Member
                    • Sep 2008
                    • 37

                    #10
                    Kevin,

                    After changing my code I now get only the dates ...

                    2009-02-24-10.57.10.000000
                    2009-02-24-10.57.10.000000
                    2009-02-24-10.57.19.000000
                    2009-02-24-10.57.23.000000
                    2009-02-24-10.57.24.000000
                    2009-02-24-10.57.50.000000
                    2009-02-24-10.57.50.000000
                    2009-02-24-10.57.50.000000
                    2009-02-24-10.57.50.000000
                    2009-02-24-10.57.50.000000
                    2009-02-24-10.51.8.000000
                    2009-02-24-10.51.8.000000
                    2009-02-24-10.51.8.000000
                    2009-02-24-10.51.16.000000
                    2009-02-24-10.54.4.000000
                    2009-02-24-10.54.4.000000

                    I do not get the rest of the line, i.e.

                    I should be getting ...

                    2009-02-24-10.57.10.000000 fem.facade.intf .caseSearch
                    2009-02-24-10.57.10.000000 codetable.intf. CodeTable
                    2009-02-24-10.57.19.000000 intf.FieldLevel SecurityRuntime
                    2009-02-24-10.57.23.000000 resolveCase

                    .. so on

                    Comment

                    • KevinADC
                      Recognized Expert Specialist
                      • Jan 2007
                      • 4092

                      #11
                      change:

                      Code:
                       print "$done\n";
                      to:

                      Code:
                         print "$done $otherstuff\n";

                      Comment

                      • joeferns79
                        New Member
                        • Sep 2008
                        • 37

                        #12
                        Thanks, Kevin. Appreciate it.

                        Comment

                        • markhu
                          New Member
                          • Aug 2009
                          • 2

                          #13
                          IMHO, unpack seems like a lot of extra work.

                          Try this one-liner using regular expression:

                          Code:
                          $ perl -pi.bak -e 's/(....)(..)(..)T(..)(..)(..)/$1-$2-$3-$4.$5.$6.000000/' /tmp/junk.txt
                          Last edited by numberwhun; Aug 27 '09, 02:02 AM. Reason: Please use code tags!

                          Comment

                          • numberwhun
                            Recognized Expert Moderator Specialist
                            • May 2007
                            • 3467

                            #14
                            Originally posted by markhu
                            IMHO, unpack seems like a lot of extra work.

                            Try this one-liner using regular expression:

                            Code:
                            $ perl -pi.bak -e 's/(....)(..)(..)T(..)(..)(..)/$1-$2-$3-$4.$5.$6.000000/' /tmp/junk.txt
                            And if your going to do that, take it one step further and do:

                            Code:
                            $ perl -pi.bak -e 's/(\d{,4})(\d{,2})(\d{2})T(\d{,2})(\d{,2})(\d{,2})/$1-$2-$3-$4.$5.$6.000000/' /tmp/junk.txt
                            A bit more elegant, but also untested at the moment, but should work none the less (unless I, without looking, messed up the options in the curly brackets).

                            By the way, please do use code tags around any code you put into the forums. Even command likes as you have put here as they essentially have code in them.

                            Regards,

                            Jeff

                            Comment

                            • nithinpes
                              Recognized Expert Contributor
                              • Dec 2007
                              • 410

                              #15
                              Jeff's command should have been:

                              Code:
                              perl -pi.bak -e 's/(\d{4})(\d{2})(\d{2})T(\d{2})(\d{2})(\d{2})/$1-$2-$3-$4.$5.$6.000000/' /tmp/junk.txt
                              \d{,4} will set an upper limit of 4 occurences for digits(max. 4 digits) and not exact 4 occurences as in \d{4} (which is appropriate for the given sample data).

                              Comment

                              Working...