ts2hr() {
while read n rest; do
if [[ $n =~ ^[0-9][0-9]*$ ]]; then
echo "$(date -d @"$n" +"%Y-%m-%d %T")" "$rest"
else
echo "$n" "$rest"
fi
done
}
这是一些输入和输出的样子:
ts2hr <<____
1571806123 first line
# A comment?
1571720456 second date's here
Just a regular sentence.
1571547789 The last line.
____
2019-10-23 13:48:43 first line
# A comment?
2019-10-22 14:00:56 second date's here
Just a regular sentence.
2019-10-20 14:03:09 The last line.
如果该行以 unix 时间戳开头,那么应该这样做:
perl -p
-e
对传递给输入的每一行的表达式调用一个循环,并在循环结束时打印缓冲区。该表达式使用 substition 命令
s///
匹配和捕获每行开头的数字序列,并将其替换为解释为 unix 时间戳的这些数字的本地时间表示。/e
表示替换模式将作为表达式进行计算。如果您的 AWK 是Gawk,您可以使用
strftime
:将第一列中的时间戳转换为当前语言环境的默认日期/时间表示。
您可以在查看内容之前使用它来转换内容:
正如Dan 在他的回答中提到的那样,可以为 Gnu
date(1)
命令提供一个-d
带有日期或时间戳的参数,它将被视为要输出的日期。date(1)
(但是,这在 POSIX 或 BSD命令中不可用 。)@1571806800
是用于指定time_t
整数的格式。这是一个 Bash shell 函数,它充当过滤器,从输入中读取行,假设任何以全为数字的行开头的单词都是时间戳,然后以我最喜欢的格式之一将其转换为人类可读的输出。
这是一些输入和输出的样子:
您可以根据需要调整功能以处理您需要的特定输入和输出格式,以及您可用的工具。上面的函数是 Bash 主要是因为
=~
运算符使模式匹配更容易;如果你在 Bourne shell 中需要这个,你必须以不同的方式对检查进行编码,如果你确实需要它的话。使用“日期”
您不需要 perl、awk、php 或长的算术表达式。您可以使用 gnu "date" 来完成,这对于这类事情非常有用。对于其他版本的“日期”,您的 YMMV。
这里发生的是您正在指定时间并对其进行调整。时间是格林威治标准时间 1970 年 1 月 1 日午夜,即 unix 时代。(没有明确给出午夜;只要您省略一天中的时间,就会隐含地使用它。)
将 1571889039 秒的调整添加到时间中。显然,请改用您的时间戳。文档对此功能使用“相对”一词。
有一个更简洁的版本,仅由手册页中的一个示例记录,它适用于较新版本的 gnu date:
如果您需要经常操作日期,请了解您的 date 命令。它不仅仅是一个时钟;它是 shell 的日期/时间库。
对于这个的便携版本,在最坏的情况下你可以自己做数学。Unix 时间戳在POSIX XBD 4.16 Seconds since the Epoch中定义:
这是您想要的映射的倒数,因此需要一些工作*来反转它。这将使您进入分解的“POSIX UTC”,但是您可能需要一种在当前时区中对其进行格式化的方法。它似乎
date -d
不可移植,所以我不清楚是否有任何好的方法可以做到这一点。*好吧,这可能是轻描淡写。
如果您没有 gnu 日期或无法访问具有 strftime 或同等功能的编程语言,则您必须自己进行数学运算,这属于代码高尔夫领域。
那时您可能还没有时区数据库,这可能是一个巨大的实际问题,除非您可以硬编码您需要的内容。
如前所述,使用 shell 甚至 AWK 并没有真正的便携方式来做到这一点。GAWK 可以做到,但 GAWK
strftime
不适用于某些版本的 AWK,即 MAWK。MAWK 与一些流行的发行版一起使用,例如 Debian。我同意应该为此提供便携式外壳或 AWK 解决方案。但由于它不是,而且可能很多年都不会,如果有的话,最好的解决方案是只使用一种编程语言。建议使用 Perl,另一种选择是 PHP: