How do I change values with perl and regex/sed inside a file?

I'm pretty sure I am doing something stupid and I apologize for this ahead of time. I have looked at the one-liners that were suggested elsewhere on similar searches and I like the idea of them, I'm just not sure how to apply because it's not a direct swap. And if the answer is that this can't be done, then that is fine and I will script around that.

The problem: I have log files I need to send through a parser that requires the dates to be in YYYY-MM-DD. The files can be saved this way; however, some people prefer them in YYYY/MM/DD for their own viewing and send those to me. I can modify one or two dates with sed and this works beautifully; however, when there are 2-3+ years in the files, it would be nice not to have to do it manually for each date.

My code (I have left the debugging commands in place):

use strict;

use File::Copy;
use Getopt::Std;

my %ARGS = ();
getopts('f:v', \%ARGS);

my $file = $ARGS{f};

&main();

sub main($)
{
    open (FIN, "<$file") || die ("Cannot open file");
    print "you opened the file\n";
while (<FIN>) {
    my $line = $_;
    if ($line =~ /(\d*)\/(\d*)\/(\d*) /i) {
        #print "you are in the if";
        my $year = $1;
        my $month = $2;
        my $day = $3;

        print $line;
        print "\nyou have year $1\n";
        print "you have month $2\n";
        print "you have day $3\n";

        s/'($1\/$2\/$3)/$1-$2-$3'/;

    }
}

close FIN;
}

I can see that the regex is getting the right values into my variables but the original line is not being replaced in the file.

Questions:

1) Should this be possible to do within the same file or do I need to output it to a different file? Looking at other answers, same file should be fine. 2) Does the file need to be opened in another way or somehow set to be written to rather than merely running the replace command like I do with sed? <--I am afraid that the failure may be in here somewhere simple that I am overlooking.

Thanks!

Answers


perl -pi.bak -e 's|(\d{4})/(\d\d)/(\d\d)|$1-$2-$3|g;' input

Replace input with your log file name. A backup file input.bak will be created in case you ever need the original data.


You never write to the file. With sed, you'd use -i, and you can do exactly the same in Perl.

perl -i -pe's{(\d{4})/(\d{2})/(\d{2})}{$1-$2-$3}g' file

Or with a backup:

perl -i~ -pe's{(\d{4})/(\d{2})/(\d{2})}{$1-$2-$3}g' file

That's equivalent to

local $^I = '';  # Or for the second:  local $^I = '~';
while (<>) {
   s{(\d{4})/(\d{2})/(\d{2})}{$1-$2-$3}g;
   print;
}

If you didn't want to rely on $^I, you'd have to replicate its behaviour.

for my $qfn (@ARGV) {
   open($fh_in, '<', $qfn)
      or do { warn("Can't open $ARGV: $!\n"); next; };

   unlink($qfn)
      or do { warn("Can't overwrite $ARGV: $!\n"); next; };

   open(my $fh_out, '>', $qfn) {
      or do { warn("Can't create $ARGV: $!\n"); next; };

   while (<$fh_in>) {
      s{(\d{4})/(\d{2})/(\d{2})}{$1-$2-$3}g;
      print $fh_out $_;
   }
}

Need Your Help

Why does my modal jQuery dialog open multiple times?

javascript jquery jquery-ui

I want to use jQuery dialog to open answer form in a modal dialog. After loading page, for the first time, it's ok, but after that by each click it will open 2^n-1 times!!! (n is count of clicks)

Java Swing, can't see the error

java swing graphics jpanel paintcomponent

I am at a very strange problem, I have a customized JPanel, which I want to draw a circle, but nothing happens ... here is my source, hope somebody sees the mistake, I can't find it.

About UNIX Resources Network

Original, collect and organize Developers related documents, information and materials, contains jQuery, Html, CSS, MySQL, .NET, ASP.NET, SQL, objective-c, iPhone, Ruby on Rails, C, SQL Server, Ruby, Arrays, Regex, ASP.NET MVC, WPF, XML, Ajax, DataBase, and so on.