Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/date/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在Bash中将时间戳转换为日期?_Bash_Date_Unix Timestamp - Fatal编程技术网

如何在Bash中将时间戳转换为日期?

如何在Bash中将时间戳转换为日期?,bash,date,unix-timestamp,Bash,Date,Unix Timestamp,我需要一个shell命令或脚本,用于将Unix时间戳转换为日期。输入可以来自第一个参数,也可以来自stdin,允许以下使用模式: ts2date 1267619929 及 这两个命令都应该输出“Wed Mar 3 13:38:49 2010”。我自己编写了一个脚本: #!/bin/bash LANG=C if [ -z "$1" ]; then if [ "$(tty)" = "not a tty" ]; then p=`cat`; else

我需要一个shell命令或脚本,用于将Unix时间戳转换为日期。输入可以来自第一个参数,也可以来自stdin,允许以下使用模式:

ts2date 1267619929


这两个命令都应该输出“Wed Mar 3 13:38:49 2010”。

我自己编写了一个脚本:

#!/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); }'
在PHP中


您可以使用以下简单的awk脚本:

#!/bin/gawk -f   
{ print strftime("%c", $0); }
示例用法:

$ echo '1098181096' | ./a.awk 
Tue 19 Oct 2004 03:18:16 AM PDT
$

在通用Linux发行版的更高版本上,您可以使用:

date -d @1267619929

例如,您可以使用GNU日期

$ sec=1267619929
$ date -d "UTC 1970-01-01 $sec secs"


此版本与chiborg的回答类似,但它不需要外部
tty
cat
。它使用
date
,但也可以轻松地使用
gawk
。您可以更改shebang并将双方括号替换为单方括号,这也将在
sh
中运行

#!/bin/bash
LANG=C
if [[ -z "$1" ]]
then
    if [[ -p /dev/stdin ]]    # input from a pipe
    then
        read -r p
    else
        echo "No timestamp given." >&2
        exit
    fi
else
    p=$1
fi
date -d "@$p" +%c
date-r

在MacOSX上适用于我。

我在转换日志文件或监视日志文件时使用此选项:

tail -f <log file> | gawk \
'{ printf strftime("%c", $1); for (i=2; i<NF; i++) printf $i " "; print $NF }'
tail-f |目瞪口呆\

{printf strftime(“%c”,$1);用于(i=2;i在这个答案中,我复制了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
例如:

$ date Tue Mar 22 16:47:06 CST 2016 $ date -d "Tue Mar 22 16:47:06 CST 2016" "+%s" 1458636426 $ date +%s 1458636453 $ date -d @1458636426 Tue Mar 22 16:47:06 CST 2016 $ date --date='@1458636426' Tue Mar 22 16:47:06 CST 2016 $date 2016年3月22日星期二16:47:06 CST $date-d“2016年3月22日星期二16:47:06 CST”+%s 1458636426 $date+%s 1458636453 $date-d@1458636426 2016年3月22日星期二16:47:06 CST $date--date='@1458636426' 2016年3月22日星期二16:47:06 CST
自Bash 4.2以来,您可以使用
printf
%(datefmt)T
格式:

$ printf '%(%c)T\n' 1267619929
Wed 03 Mar 2010 01:38:49 PM CET
这很好,因为它是一个shell内置。datefmt的格式是一个被
strftime(3)
接受的字符串(请参见
man3strftime
)。这里
%c
是:

%c
当前事件的首选日期和时间表示形式 地点


现在,如果您想要一个脚本,该脚本接受一个参数,如果未提供任何参数,则读取stdin,您可以继续执行以下操作:

#!/bin/bash

if (($#)); then
    printf '%(%c)T\n' "$@"
else
    while read -r line; do
        printf '%(%c)T\n' "$line"
    done
fi

在OSX或BSD中,有一个等效的
-r
标志,它显然带有unix时间戳。下面是一个运行日期四次的示例:第一次运行日期一次,以显示它是什么;一次使用
%s
转换为unix时间戳,最后一次使用
-r
%s
提供的内容转换回unix一串

$  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

您可以像这样从时间戳获取格式化日期

date +'%Y-%m-%d %H:%M:%S' -d "@timestamp"

虽然不是纯bash,但下面的脚本将使用perl将字符串中长度为13的时间戳转换为本地时区中的等效日期

timestamp_to_date.sh 输入 输出
我使用这种跨平台单衬套:

date -d @1267619929 2>/dev/null || date -r 1267619929

它应该在macOS和流行的Linux发行版的更高版本中都能工作。

我必须转换bash历史记录中的内联时间戳,以便对我有意义

也许其他读者也会对下面的答案感兴趣。 原始sed内联代码的荣誉归于@Gabriel

cat ~/.bash_history | sed "s/^#\([0-9]\+\)$/echo -n '#'; date -u --d @\1 '\+\%Y-\%m-\%d \%T'/e" | less


这不适合第一次使用-有时我不想回显TS,而是使用参数。在一些旧的busybox版本上,
date-s@
不起作用,而
awk
仍然起作用!一个没有stdin的示例也会有帮助。很好,但我只想使用bash。+1:答案非常完整,我认为date比gawk快。@Bruno,你怎么知道date比gawk快呢?@Bruno,@ghostdog74:在我的系统中,
gawk
date
快(大约)15%,这是一个定时的
循环,只包含
gawk'开始{print strftime(%c),1256571985;}“
date-d'@1256571985'+%c
,输出重定向到
/dev/null
。对我来说,date比gawk稍微快(5%)(mac osx 10.9.2,date 8.23,gawk 4.1.1),但(g)awk的真正优势是接受一列多个时间戳的管道(见下面的答案),这使脚本的速度(例如,对于1000个时间戳)达到250倍。请注意,我的答案符合问题中所述的OP要求,但现在接受的答案不符合。是的,但它不能处理几分之一秒的时间。这让人困惑,因为它在大多数linux系统上都不能以这种方式工作,因为:freddy@hades~%date--帮助|grep--r-r,-reference=FILE显示文件的最后修改时间虽然此答案上的注释是正确的,但这不是rafa的错,也不会减少他的答案。一行:
date-d@$(date-u+%s)
这个
@
是干什么用的?我在GNU手册页中根本看不到。@mehaase-手册页注意到日期字符串太复杂,无法在手册页中记录,因此在info:info'(coreutils)中进行了描述日期调用'
brew install coreutils;gdate-d@1267619929
info'日期输入格式'
直接进入
date
的格式化信息节点,并带有相关的Robert Grudin引号,然后是一个格式说明符菜单。如果您已经有一个时间戳值,只需在OS X yo中查找等效的日期即可你可以在命令行输入:date-r 1509453417这是真的。如果你看我的答案,我实际上是在演示。正是我想要的,可以缩短为
awk'{printf strftime(“%c:”,$1);$1=“”;print$0;}'
其他方式:date-ud“@1585667718”+“%Y-%m-%d%H:%m:%s
$ 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
date +'%Y-%m-%d %H:%M:%S' -d "@timestamp"
#!/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"}
date -d @1267619929 2>/dev/null || date -r 1267619929
cat ~/.bash_history | sed "s/^#\([0-9]\+\)$/echo -n '#'; date -u --d @\1 '\+\%Y-\%m-\%d \%T'/e" | less