私たちは異なる時間帯にいくつかのサーバーを持っています。日付を含むtable.htmlがあります。私たちは各サーバーが正しい日付を持つことを望んでいるので、私は次のように考えます。
- we should convert the time on server "A" to unix time.
- then on server "B" back from unix time to normal time.
尋ねる:それでは、通常の日付<-> Unixの時間をどのように変換しますか?したがって、table.htmlをその場で編集しますか?
サーバー「A」:
cat table.html
<tr><td>X</td><td>X</td><td>X</td><td>X</td><td>X</td><td>X</td><td>2014-05-23-12.23.00.000000</td></tr>
<tr><td>X</td><td>X</td><td>X</td><td>X</td><td>X</td><td>X</td><td>2014-05-26-17.00.00.000000</td></tr>
<tr><td>X</td><td>X</td><td>X</td><td>X</td><td>X</td><td>X</td><td>NA</td></tr>
サーバー「B」:
cat table.html
<tr><td>X</td><td>X</td><td>X</td><td>X</td><td>X</td><td>X</td><td>1400840580</td></tr>
<tr><td>X</td><td>X</td><td>X</td><td>X</td><td>X</td><td>X</td><td>1401116400</td></tr>
<tr><td>X</td><td>X</td><td>X</td><td>X</td><td>X</td><td>X</td><td>NA</td></tr>
ps:サーバーには、「date」コマンドの「-d」パラメーターがありません!おそらくパール?
ps2:「X」は検閲データであり、何でも構いません。
ps3:時には7番目の列に日付がなく、「NA」と書かれます。
更新:答えを試しました。
$ cat a.txt
<tr><td>X</td><td>X</td><td>X</td><td>X</td><td>X</td><td>X</td><td>2014-05-23-12.23.00.000000</td></tr>
<tr><td>X</td><td>X</td><td>X</td><td>X</td><td>X</td><td>X</td><td>2014-05-26-17.00.00.000000</td></tr>
<tr><td>X</td><td>X</td><td>X</td><td>X</td><td>X</td><td>X</td><td>NA</td></tr>
$
$ cat b.txt
#!/usr/bin/env perl
use warnings;
use POSIX;
# Pass the option -i to import from unix time to local time.
# Without the option, export from local time to unix time.
$import = 0;
if (@ARGV && $ARGV[1] eq "-i") {$import = 1}
while (<STDIN>) {
@F = split m!(<td>.*</td>)!;
# Field 13 contains a potential date.
if ($import && $F[13] =~ m!(<td>)([0-9]+)(\.[0-9]*</td>)!) {
# Import unix time to local time
($s,$n,$h,$d,$m,$y,@_tail) = localtime($2);
$F[13] = sprintf "$1%04d-%02d-%02d-$02d.%02d.%02d$3", $y, $m, $d, $h, $n, $s;
}
if (!$import && $F[13] =~ m!(<td>)([0-9]+)-([0-9]+)-([0-9]+)-([0-9]+)\.([0-9]+)\.([0-9]+)(\.[0-9]*</td>)!) {
# Export local time to unix time
$t = POSIX.mktime($7, $6, $5, $4, $3, $2);
$F[13] = "$1$t$8";
}
$_ = "@F";
}
$
$
$ perl b.txt a.txt
Use of uninitialized value $ARGV[1] in string eq at b.txt line 7.
Use of uninitialized value $F[13] in pattern match (m//) at b.txt line 16, <STDIN> line 1.
Use of uninitialized value $F[13] in pattern match (m//) at b.txt line 16, <STDIN> line 2.
Use of uninitialized value $F[13] in pattern match (m//) at b.txt line 16, <STDIN> line 3.
^C
$
答え1
常にGMT日付を保存することをお勧めします。タイムゾーン情報を含む日付にこれが本当に不便な場合です。日付を指定しないままにしておくのは良い考えではありません。
このデータ型を使用する必要がある場合、Perlはローカル日付をGMT日付に変換するか、その逆に変換する素晴らしいツールです。
通常、正規表現を使用してHTMLを解析することはお勧めできません。しかし、入力フォーマットが非常に制限されているかどうかは重要ではありません。私の答えは、あなたの例のように、テーブル行が常に1行にあると仮定します。そうでない場合は、おそらく実際のHTMLパーサーを使用する必要があります。HTML::Parser
。
#!/usr/bin/env perl
use warnings;
use POSIX;
# Pass the option -i to import from unix time to local time.
# Without the option, export from local time to unix time.
$import = 0;
if (@ARGV && $ARGV[0] eq "-i") {$import = 1}
while (<STDIN>) {
@F = split m!(<td>.*</td>)!;
# Field 13 contains a potential date.
if ($import && @F >= 13 && $F[13] =~ m!(<td>)([0-9]+)(\.[0-9]*</td>)!) {
# Import unix time to local time
($s,$n,$h,$d,$m,$y,@_tail) = localtime($2);
$F[13] = sprintf "$1%04d-%02d-%02d-$02d.%02d.%02d$3", $y, $m, $d, $h, $n, $s;
}
if (!$import && @F >= 13 && $F[13] =~ m!(<td>)([0-9]+)-([0-9]+)-([0-9]+)-([0-9]+)\.([0-9]+)\.([0-9]+)(\.[0-9]*</td>)!) {
# Export local time to unix time
$t = POSIX.mktime($7, $6, $5, $4, $3, $2);
$F[13] = "$1$t$8";
}
$_ = "@F";
}
(警告、テストされていないコード!)
答え2
一方perl
通行:
$ perl -MTime::Local -nle 'push @day,$1 if /.*\<td\>(.*)\<\/td\>/;
END {
for (@day) {
if (/^\d/) {
($y,$m,$d,$h,$mi,$s,@tail) = split("-|\\.",$_);
print timelocal($s,$mi,$h,$d,$m-1,$y);
}
}
}' file
1400822580
1401098400
現在の場所でファイルを変更するには:
$ perl -MTime::Local -i.bak -nle '$date = $1 if /.*\<td\>(.*)\<\/td\>/;
if ($date =~ /^\d/) {
($y,$m,$d,$h,$mi,$s,@tail) = split("-|\\.",$date);
$t = timelocal($s,$mi,$h,$d,$m-1,$y);
$_ =~ s/$date/$t/e;
}' file
<tr><td>X</td><td>X</td><td>X</td><td>X</td><td>X</td><td>X</td><td>1400822580</td></tr>
<tr><td>X</td><td>X</td><td>X</td><td>X</td><td>X</td><td>X</td><td>1401098400</td></tr>
<tr><td>X</td><td>X</td><td>X</td><td>X</td><td>X</td><td>X</td><td>NA</td></tr>
Unix時間を現地時間に変換するには:
$ perl -i -nle '$unixtime = $1 if /.*\<td\>(.*)\<\/td\>/;
if ($unixtime =~ /\d/) {
($s,$mi,$h,$d,$m,$y,@tail) = localtime($unixtime);
$date = sprintf "%04d-%02d-%02d-%02d.%02d.%04d", $y+1900, $m+1, $d, $h, $mi, $s;
$_ =~ s/$unixtime/$date/e;
}
' file