如何使用bash更改日志文件中的日期格式,避免while循环



这不是一个新问题,但细节使它有所不同。

我的输入日志文件看起来像:

TEMP MON -=- Sat Aug 15 02:20:24 EEST 2020 -=- 48.6
TEMP MON -=- Sat Aug 15 02:20:50 EEST 2020 -=- 49.1
TEMP MON -=- Sat Aug 15 02:21:13 EEST 2020 -=- 49.1
TEMP MON -=- Sat Aug 15 02:21:44 EEST 2020 -=- 49.1
TEMP MON -=- Sat Aug 15 02:21:45 EEST 2020 -=- 48.6
TEMP MON -=- Sat Aug 15 02:21:52 EEST 2020 -=- 49.1
TEMP MON -=- Sat Aug 15 02:21:53 EEST 2020 -=- 48.6
TEMP MON -=- Sat Aug 15 02:21:54 EEST 2020 -=- 49.6
TEMP MON -=- Sat Aug 15 02:21:56 EEST 2020 -=- 49.1
TEMP MON -=- Sat Aug 15 02:21:57 EEST 2020 -=- 49.1

输出应该看起来像:

TEMP MON -=- 2020-08-15_02:20:24 EEST -=- 48.6
...

因此,使用更改bash中日期的格式就足够简单了

date -d ${date_in_current_format} "+DATE_IN_NEW_FORMAT"

使用while循环迭代日志文件并逐行更改日期也是可能的(尽管效率很低((再次参见第一个链接(。

然而,我正在寻找一个bash解决方案,它使用sedperl(或awk或其他任何相关内容(来执行相同的任务。

我尝试过但仍然不起作用的提示是以下搜索和替换功能:

perl -pe "s/(.*) -=- (.*) -=- (.*)/1 -=- $( date 2 "+%Z %Y-%m-%d_%H:%M:%S" ) -=- 3/" <file>

sed类似:

sed "s:(.*) -=- (.*) -=- (.*):1 -=- $( date -d 2 "+%Z %Y-%m-%d_%H:%M:%S" ) -=- 3:" <file>

在这两种情况下,问题都是我无法获得搜索和替换替换"\2〃;以便在bashdate命令执行中进行扩展。

由于awk只使用字符串函数,您可以避免调用GNU awk日期时间函数或外部命令date,因为我们只想修改月份并重新排序数据。

> cat tst.awk
BEGIN { OFS=FS="-=-" }
{
split($2, arr, " ")
m=(index("JanFebMarAprMayJunJulAugSepOctNovDec", arr[2])+2)/3
$2=sprintf(" %04d-%02d-%02d_%s %s ", arr[6], m, arr[3], arr[4], arr[5])
print
}

用法:

> awk -f tst.awk file
TEMP MON -=- 2020-08-15_02:20:24 EEST -=- 48.6
TEMP MON -=- 2020-08-15_02:20:50 EEST -=- 49.1
TEMP MON -=- 2020-08-15_02:21:13 EEST -=- 49.1
TEMP MON -=- 2020-08-15_02:21:44 EEST -=- 49.1
TEMP MON -=- 2020-08-15_02:21:45 EEST -=- 48.6
TEMP MON -=- 2020-08-15_02:21:52 EEST -=- 49.1
TEMP MON -=- 2020-08-15_02:21:53 EEST -=- 48.6
TEMP MON -=- 2020-08-15_02:21:54 EEST -=- 49.6
TEMP MON -=- 2020-08-15_02:21:56 EEST -=- 49.1
TEMP MON -=- 2020-08-15_02:21:57 EEST -=- 49.1

您可以使用此awk解决方案:

awk 'BEGIN {
FS=OFS=" -=- "
}
{
cmd = sprintf("TZ=EET date -d "%s" +"%Y-%m-%%d_%T %Z"", $2);
if ((cmd | getline output) > 0)
$2 = output
close(cmd)
} 1' file
TEMP MON -=- 2020-08-15_02:20:24 EEST -=- 48.6
TEMP MON -=- 2020-08-15_02:20:50 EEST -=- 49.1
TEMP MON -=- 2020-08-15_02:21:13 EEST -=- 49.1
TEMP MON -=- 2020-08-15_02:21:44 EEST -=- 49.1
TEMP MON -=- 2020-08-15_02:21:45 EEST -=- 48.6
TEMP MON -=- 2020-08-15_02:21:52 EEST -=- 49.1
TEMP MON -=- 2020-08-15_02:21:53 EEST -=- 48.6
TEMP MON -=- 2020-08-15_02:21:54 EEST -=- 49.6
TEMP MON -=- 2020-08-15_02:21:56 EEST -=- 49.1
TEMP MON -=- 2020-08-15_02:21:57 EEST -=- 49.1

在Perl:中使用核心模块Time::Piece

perl -MTime::Piece -pe 's/-=-s+K(.*)(?=s+-=-)/convert($1)/e;
sub convert {
$s = $_[0];
$s =~ s/s+EESTs+/ /;
$t = Time::Piece->strptime($s, "%a %b %d %T %Y");
$res = $t->strftime("%Y-%m-%d_%H:%M:%S");
"$res EEST"
}' file

最新更新