Gary Gary - 2 months ago 6x
Perl Question

Global Substitution

Hi I am using the below code to replace date formats but I am unable to figure out how to globally change all dates. Currently, the script finds and replaces the dates correctly, but it only does it for the first date found within a line but skips the rest of that line. So if there is another date that needed to be change within the same line it ignores it. I've attempted using global substitution but to no avail. If anyone could give me an idea I would very much appreciate it.

use strict;
use Time::Piece ();

my $file = $ARGV[0];
open FILE, $file or die;

while ( my $line = <FILE> ) {
chomp $line;
my ($date) = $line =~ m/([A-Z][a-z][a-z] [ \d]{2} \d{4} \d{2}:\d{2}[AP]M)/;

if ($date eq ''){
print "$line\n";
my $new_dt = Time::Piece->strptime($date, '%b %d %Y %H:%M%p')->strftime('%Y-%m-%d %H:%M:%S');

$line =~ s/$date/$new_dt/g;
print "$line\n";

close FILE;
print "\n";

EDIT: Added example


May 15 2007 12:00AM, , 1, 0, Feb 2 2003 12:00PM


2007-05-15 00:00:00, , 1, 0, Feb 2 2003 12:00PM


You are replacing all the datetimes that are identical to the first datetime of the line. You don't even try to find any other datetimes.

while (<>) {
    s{([A-Z][a-z][a-z] [ \d]\d \d{4} \d{2}:\d{2}[AP]M)}{
        Time::Piece->strptime($1, '%b %d %Y %I:%M%p')->strftime('%Y-%m-%d %H:%M:%S')


As it turns out, the subject you chose for your question was quite appropriate :)

Note: I changed %H (hour as 0..23) to the more appropriate than %I (hour as 1..12).