我需要一个shell命令或脚本,将Unix时间戳转换为日期。输入可以来自第一个参数,也可以来自stdin,允许以下使用模式:
ts2date 1267619929
and
echo 1267619929 | ts2date
这两个命令都应该输出“Wed Mar 3 13:38:49 2010”。
我需要一个shell命令或脚本,将Unix时间戳转换为日期。输入可以来自第一个参数,也可以来自stdin,允许以下使用模式:
ts2date 1267619929
and
echo 1267619929 | ts2date
这两个命令都应该输出“Wed Mar 3 13:38:49 2010”。
当前回答
我喜欢以前的特殊情况下的解决方案:printf '%(%c)T\n' $timestamp(如果你有Bash>=4.2), date -d @$timestamp(如果你有GNU Coreutils >= 5.3.0), date -r $timestamp(如果你是BSD/MacOS),但我需要一些更可移植的东西,我选择了jq,我到处都有JSON的帮助:
jq 'todate' <<< $timestamp
可以在函数中使用,以获得所需的效果:
ts2date() { [[ -n "$1" ]] && { jq 'todate' <<< $1 ; true;} || jq 'todate' ; }
其他回答
我在转换日志文件或监控它们时使用这个:
tail -f <log file> | gawk \
'{ printf strftime("%c", $1); for (i=2; i<NF; i++) printf $i " "; print $NF }'
虽然不是纯bash,但下面的脚本将使用perl将字符串中长度为13的时间戳转换为本地时区中的等效日期
timestamp_to_date.sh
#!/usr/bin/env bash
IT=$(cat /dev/stdin)
re='(.*)([0-9]{13})(.*)'
while [[ $IT =~ $re ]]; do
TIMESTAMP=${BASH_REMATCH[2]}
AS_DATE=$(echo "$TIMESTAMP" | perl -pe 's/([\d]{10})([\d]{3})/localtime $1/eg;')
IT="${IT/$TIMESTAMP/$AS_DATE}"
done
echo "$IT"
输入
{"timestamp":"1573121629939","level":"DEBUG","thread":"http-nio-15372-exec-3","logger":"org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor"}
输出
$ cat input | timestamp_to_date.sh
{"timestamp":"Thu Nov 7 06:13:49 2019","level":"DEBUG","thread":"http-nio-15372-exec-3","logger":"org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor"}
我自己写了一个脚本:
#!/bin/bash
LANG=C
if [ -z "$1" ]; then
if [ "$(tty)" = "not a tty" ]; then
p=`cat`;
else
echo "No timestamp given."
exit
fi
else
p=$1
fi
echo $p | gawk '{ print strftime("%c", $0); }'
在这个答案中,我复制了Dennis Williamson的答案,并对其稍加修改,以便在将许多时间戳的列输出到脚本时大幅提高速度。例如,在我的机器上,用xargs -n1将1000个时间戳传送到原始脚本需要6.929秒,而修改后的版本需要0.027秒:
#!/bin/bash
LANG=C
if [[ -z "$1" ]]
then
if [[ -p /dev/stdin ]] # input from a pipe
then
cat - | gawk '{ print strftime("%c", $1); }'
else
echo "No timestamp given." >&2
exit
fi
else
date -d @$1 +%c
fi
在OSX或BSD中,有一个等效的-r标志,它显然接受unix时间戳。下面是一个运行date四次的示例:一次是第一次约会,以显示它是什么;一个用于转换为使用%s的Unix时间戳,最后一个使用-r将%s提供的内容转换回字符串。
$ date; date +%s; date -r `date +%s`
Tue Oct 24 16:27:42 CDT 2017
1508880462
Tue Oct 24 16:27:42 CDT 2017
至少在我的机器上还能用。
$ uname -a
Darwin XXX-XXXXXXXX 16.7.0 Darwin Kernel Version 16.7.0: Thu Jun 15 17:36:27 PDT 2017; root:xnu-3789.70.16~2/RELEASE_X86_64 x86_64