从命令行自动调整多个文本文件中的日期和时间信息

从命令行自动调整多个文本文件中的日期和时间信息

我有一个文件夹,其中包含几个文本文件,其内容如下:

text text
more text
Date: Thu, 31 Dec 2015 23:53:51 +0000 (UTC)
more text
some more

我希望日期和时间与我的时区相符(就我而言,如果显示“+0000 (UTC)”,则必须添加 1 小时,以适应冬令时)

因此结果应该是相同的文件(相同的文件名或如果您想要“adjusteddate_originalfilename”),其中包含:

text text
more text
Date: Fri, 1 Jan 2016 00:53:51
more text
some more

请注意,需要编辑的行以“Date: ”开头(这是唯一的,文本文件中没有其他“Date: ”),以“+0000 (UTC)”结尾。并且,只有当行结尾为“+0000 (UTC)”时,才会进行编辑。

在这些文件中,我还有其他文件:

text text
text text
Date: Mon, 12 Oct 2015 23:07:29 +0200
text text
text text

这些不需要调整,(事实上我希望删除“+0200”)。

这些更正将自动定期对“/home/user/folder01”中包含的所有文件进行(例如,我不在这台计算机前)。我正在运行 Ubuntu 15.04。

答案1

您可以使用 GNUdate将该时间转换为您当地时区。

 awk '/^Date:.*UTC/ {cmd="date -Rd \"" substr($0,6) "\""; cmd | getline new; close(cmd); $0="Date: " new} 1' file
text text
more text
Date: Fri, 01 Jan 2016 01:53:51 +0200
more text
some more

如果您有 GNU awk,您可以使用以下命令就地更改当前目录中的所有文件:

gawk -i inplace '/^Date:.*UTC/ {cmd="date -Rd \"" substr($0,6) "\""; cmd | getline new; close(cmd); $0="Date: " new} 1' *

如果没有 GNU awk,请使用:

for f in *
do
    awk '/^Date:.*UTC/ {cmd="date -Rd \"" substr($0,6) "\""; cmd | getline new; close(cmd); $0="Date: " new} 1' "$f" >tmp && mv tmp "$f"
done

怎么运行的

  • -i inplace

    这告诉 GNU awk 就地更改文件。这需要现代 GNU awk。如果您使用 Mike 的 awk,则改用如上所示的 bash 循环。

  • /^Date:.*UTC/ {cmd="date -Rd \"" substr($0,6) "\""; cmd | getline new; close(cmd); $0="Date: " new}

    这将选择以 开头Date:UTC在同一行包含 的行。对于这些行,命令date -Rd将在包含日期的行部分运行。结果存储在变量 中new。然后,当前行($0在 awk 中用 表示)将替换为包含新日期的行。

  • 1

    这是 awk 中 print-the-line 的神秘简写。

多行 GNU 版本

如果您希望脚本分布在多行上:

gawk -i inplace '

/^Date:.*UTC/ {
    cmd="date -Rd \"" substr($0,6) "\""; cmd | getline new
    close(cmd)
    $0="Date: " new
}

1
' file

一些改进(非 GNU 版本)

  1. 上面的代码查找以 开头Date:且包含字母 的行UTC。在我看来这已经足够好了。然而,问题更具体地要求查找以 开头Date:和结尾的行+0000 (UTC)

  2. 该问题还要求消除+0200非 UTC 日期变更线的尾随部分。

添加这两个改进后,代码变成:

for f in *
do
    awk '/Date: .* [+]0200$/{sub(/ [+]0200$/,"")} /^Date: .* [+]0000 [(]UTC[)]$/ {cmd="date -Rd \"" substr($0,6) "\""; cmd | getline new; close(cmd); $0="Date: " new} 1' "$f" >tmp && mv tmp "$f"
done

这段代码更精确,但也更挑剔。例如,这段代码坚持要求以 结尾的行在+0000 (UTC)它之前会改变它。因此,带有尾随空格的行(在编辑器中可能不可见)将不是可以改变。这是否好,由你来决定。

答案2

使用 Perl:

perl -pe 's/Date: (.* \+0000 \(UTC\))/$1/?$_="Date: ".`LC_TIME=en_US.UTF-8 date -d "$_" "+%a, %d %b %Y %T"`:s/(Date:.*) \+[0-9]{4}/$1/' in
  • 如果s/Date: (.* \+0000 \(UTC\))/$1/可以进行替换,即用 之后的部分替换整行Date:,则打印 ,Date:然后打印 的输出,使用的值LC_TIME=en_US.UTF-8 date -d "$_" "+%a, %d %b %Y %T"将替换部分转换为当前时区;否则,如果可以进行替换,即用 之前的部分替换整行,则打印替换的部分;如果无法进行替换,则打印整行。LC_TIMEen_US.UTF-8s/(Date:.*) \+[0-9]{4}/$1/+NNNN

这意味着当前LC_TIME值已经设置为en_US.UTF-8(或等效值),LC_TIME=en_US.UTF-8可以安全地删除该部分:

perl -pe 's/Date: (.* \+0000 \(UTC\))/$1/?$_="Date: ".`date -d "$_" "+%a, %d %b %Y %T"`:s/(Date:.*) \+[0-9]{4}/$1/' in
% cat in
line
Date: Thu, 31 Dec 2015 23:53:51 +0000 (UTC)
Date: Mon, 12 Oct 2015 23:07:29 +0200
% perl -pe 's/Date: (.* \+0000 \(UTC\))/$1/?$_="Date: ".`LC_TIME=en_US.UTF-8 date -d "$_" "+%a, %d %b %Y %T"`:s/(Date:.*) \+[0-9]{4}/$1/' in
line
Date: Fri, 01 Jan 2016 00:53:51
Date: Mon, 12 Oct 2015 23:07:29

要就地编辑文件并将其应用于多个文件,您可以添加开关-i和传递*而不是文件名:

% cat in
line
Date: Thu, 31 Dec 2015 23:53:51 +0000 (UTC)
Date: Mon, 12 Oct 2015 23:07:29 +0200
% cat in1
line
Date: Thu, 31 Dec 2015 23:53:51 +0000 (UTC)
Date: Mon, 12 Oct 2015 23:07:29 +0200
user@user-X550CL ~/tmp % perl -i -pe 's/Date: (.* \+0000 \(UTC\))/$1/?$_="Date: ".`LC_TIME=en_US.UTF-8 date -d "$_" "+%a, %d %b %Y %T"`:s/(Date:.*) \+[0-9]{4}/$1/' *
user@user-X550CL ~/tmp % cat in
line
Date: Fri, 01 Jan 2016 00:53:51
Date: Mon, 12 Oct 2015 23:07:29
user@user-X550CL ~/tmp % cat in1
line
Date: Fri, 01 Jan 2016 00:53:51
Date: Mon, 12 Oct 2015 23:07:29

答案3

perl删除awk部分datefoo用您的文件名替换

perl -pe 's/^(Date:.*)\+[0-9]{4}$/$1/' foo | \
    awk -F'Date:' '/(UTC)/ {system("echo Date: $(date -d \""$2"\" +\"%a, %d %b %Y %H:%M:%S\") "); next} {print $0}'

例子

cat dates

text text
more text
Date: Thu, 31 Dec 2015 23:53:51 +0000 (UTC)
more text
some more
text text
text text
Date: Mon, 12 Oct 2015 23:07:29 +0200
text text
text text
text text
more text
Date: Fri, 1 Jan 2016 01:53:51
more text
some more
perl -pe 's/^(Date:.*)\+[0-9]{4}$/$1/' dates | \
    awk -F'Date:' '/(UTC)/ {system("echo Date: $(date -d \""$2"\" +\"%a, %d %b %Y %H:%M:%S\") "); next} {print $0}'
text text
more text
Date: Fri, 01 Jan 2016 01:53:51
more text
some more
text text
text text
Date: Mon, 12 Oct 2015 23:07:29 
text text
text text
text text
more text
Date: Fri, 1 Jan 2016 01:53:51
more text
some more

相关内容