1

私は愚かなことをしていると確信しており、これについて事前に謝罪します。同様の検索で他の場所で提案されたワンライナーを見てきましたが、それらのアイデアが気に入っています。直接交換ではないため、適用方法がわかりません. 答えが、これができないというものであれば、それで問題ありません。スクリプトを作成します。

問題: 日付を YYYY-MM-DD にする必要があるパーサーを介して送信する必要があるログ ファイルがあります。ファイルはこの方法で保存できます。ただし、YYYY/MM/DD で表示する方が好みで、私に送ってくださる方もいます。sed を使用して 1 つまたは 2 つの日付を変更できますが、これはうまく機能します。ただし、ファイルに 2 ~ 3 年以上の年がある場合は、日付ごとに手動で行う必要はありません。

私のコード(デバッグコマンドをそのまま残しました):

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;
}

正規表現が変数に正しい値を取得していることがわかりますが、元の行はファイルで置き換えられていません。

質問:

1)これは同じファイル内で実行できるはずですか、それとも別のファイルに出力する必要がありますか? 他の回答を見ると、同じファイルで問題ないはずです。2) sed で行うように単に replace コマンドを実行するのではなく、ファイルを別の方法で開くか、何らかの方法で書き込みを設定する必要がありますか? <--私が見落としているどこか単純なところに失敗があるのではないかと心配しています。

ありがとう!

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 に答える