tags:

views:

80

answers:

4

I have a file of 1000 lines, each line in the format

filename dd/mm/yyyy hh:mm:ss

I want to convert it to read

filename mmddhhmm.ss

been attempting to do this in perl and awk - no success - would appreciate any help

thanks

+4  A: 

You can do a simple regular expression replacement if the format is really fixed:

s|(..)/(..)/.... (..):(..):(..)$|$2$1$3$4.$5|

I used | as a separator so that I do not need to escape the slashes.

You can use this with Perl on the shell in place:

perl -pi -e 's|(..)/(..)/.... (..):(..):(..)$|$2$1$3$4.$5|' file

(Look up the option descriptions with man perlrun).

Svante
so just perl - e s|(..)/(..)/.... (..):(..):(..)$|$2$1$3$4.$5| file?sorry if I'm being a bit dense here
paul44
@paul44 yes, that will send the results to the terminal. To "update" the file, you need to redirect the output to a different file, and then rename it over the original. Don't forget to quote the string too though, to stop the shell interpreting all the special characters itself.
Andy Mortimer
perl -e does not return anything. perl -pe just acts like I'm catting the file to STDOUT - no changes. I'm running: perl -pe "s|(..)/(..)/(....) (..):(..):(..)$|$2$1$3$4$5.$6|" testlistto get the year too.
paul44
If you want to have the year too, _please_ put it in front: yyyy-mm-dd; do not mix descending and ascending order of the units.
Svante
+1  A: 

Another somehow ugly approach: foreach line of code ($str here) you get from the file do something like this:

my $str = 'filename 26/12/2010 21:09:12';

my @arr1 = split(' ',$str);
my @arr2 = split('/',$arr1[1]);
my @arr3 = split(':',$arr1[2]);

my $day = $arr2[0]; 
my $month = $arr2[1]; 
my $year = $arr2[2];

my $hours = $arr3[0]; 
my $minutes = $arr3[1]; 
my $seconds = $arr3[2];

print $arr1[0].' '.$month.$day.$year.$hours.$minutes.'.'.$seconds;
Thariama
Maybe ugly, but understandable to any non-expert.
MJB
so can I open (FILELIST, "list) while $str = <FILELIST> ?
paul44
yes you can use this code to process each line of code
Thariama
thanks - perfect
paul44
I would just use `split /[\/:\s]/, $str`
Axeman
+1  A: 

Pipe your file to a perl script with:

while( my line = <> ){
    if ( $line =~ /(\S+)\s+\(d{2})\/(\d{2})/\d{4}\s+(\d{2}):(\d{2}):(\d{2})/ ) {
        print $1 . " " . $3 . $2 . $4 . $5 . '.' . $6;
    }
}

Redirect the output however you want. This says match line to: (non-whitespace>=1)whitespace>=1(2digits)/(2digits)/4digits whitepsace>=1(2digits):(2digits):(2digits)

Capture groups are in () numbered 1 to 6 left to right.

stocherilac
this is perfect - thanks everyone
paul44
dont' forget to accept an answer please
stocherilac
A: 

Using sed:

sed -r 's|/[0-9]{4} ||; s|/||; s/://; s/:/./' file.txt
  • delete the year /yyyy
  • delete the remaining slash
  • delete the first colon
  • change the remaining colon to a dot

Using awk:

awk '{split($2,d,"/"); split($3,t,":"); print $1, d[1] d[2] t[1] t[2] "." t[3]}'
Dennis Williamson