1

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!

4

2 回答 2

3

你永远不会写入文件。使用sed, 你会使用-i, 你可以在 Perl 中做同样的事情。

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

或使用备份:

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

这相当于

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

如果您不想依赖$^I,则必须复制其行为。

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 $_;
   }
}
于 2013-05-01T18:41:08.183 回答
1
perl -pi.bak -e 's|(\d{4})/(\d\d)/(\d\d)|$1-$2-$3|g;' input

将输入替换为您的日志文件名。如果您需要原始数据,将创建一个备份文件 input.bak。

于 2013-05-01T18:45:50.673 回答