我有一个文件夹,其中包含几个文本文件,其内容如下:
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 版本)
上面的代码查找以 开头
Date:
且包含字母 的行UTC
。在我看来这已经足够好了。然而,问题更具体地要求查找以 开头Date:
和结尾的行+0000 (UTC)
。该问题还要求消除
+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_TIME
en_US.UTF-8
s/(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
部分date
。foo
用您的文件名替换
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