Bashでタイムスタンプを日付に変換する方法は?


270

Unixタイムスタンプを日付に変換するシェルコマンドまたはスクリプトが必要です。入力は、最初のパラメーターまたはstdinから取得でき、次の使用パターンを可能にします。

ts2date 1267619929

そして

echo 1267619929 | ts2date

どちらのコマンドでも「Wed Mar 3 13:38:49 2010」が出力されます。

回答:


532

一般的なLinuxディストリビューションのそれ以降のバージョンでは、以下を使用できます。

date -d @1267619929

5
ワンライナー:date -d @$(date -u +%s)
Mike Atlas

26
何の@ためですか?私はそれをGNUのmanページでまったく見ていません。
Mark E. Haase、2016

13
@mehaase-マンページでは、日付文字列が複雑すぎてマンページに文書化できないことが記載されているため、info:info '(coreutils)date invocation'
MByD

10
brew install coreutils; gdate -d @1267619929
マークフォックス

2
info 'Date input formats'date、関連するRobert Grudinの引用を含むのフォーマット情報ノードに直接アクセスし、次にフォーマット指定子のメニューを表示します。
マイク

165
date -r <number>

Mac OS Xで動作します。


5
はい、しかしそれは秒の端数を処理しません。
mgold 2013年

1
そして、ほとんどのLinuxシステムではそのように機能しないため、混乱を招きます。それは、freddy @ hades〜%date --help | grep--r -r、--reference = FILE FILEの最終変更時刻を表示
frank42

1
この答えについてのコメントは真実ですが、これらはラファのせいではなく、彼の答えを損なうものではありません。
マイク

29

このバージョンは、Chiborgの回答に似ていますが、外部ttyおよびの必要がなくなりcatます。使用しますがdate、簡単に使用できますgawk。シバンを変更して、二重の角括弧を単一のものに置き換えることができます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

+1:非常に完全な答えで、日付はgawkよりも速いと思います。
ブルーノブラント

@ブルーノ、日付がgawkより速いことをどうやって知っていますか?
ghostdog74

3
@ Bruno、@ ghostdog74:私のシステムでgawkは、出力がのみにリダイレクトされるか、出力がにリダイレクトされるdateタイミングforループよりも(非常に)15%高速です。gawk 'BEGIN { print strftime("%c", 1256571985); }'date -d '@1256571985' +%c/dev/null
追って通知があるまで一時停止。

1
日付は私にとってgawk(mac osx 10.9.2、date 8.23、gawk 4.1.1)よりわずかに(5%)高速ですが、(g)awkの本当の利点は、多くのタイムスタンプの列のパイプを受け入れることです(以下の私の答え)、これにより、スクリプトは、たとえば1000のタイムスタンプに対して250倍高速になります。
webb

3
私の回答は質問に記載されているOPの要件を満たしていますが、現在受け入れられている回答は満たしていません。
追って通知があるまで一時停止。

17

たとえば、GNU日付を使用できます。

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

または

$ date -ud @1267619929

10

次の単純なawkスクリプトを使用できます。

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

使用例:

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

これは最初の使用法には適合しません-時にはTSをエコーし​​てパラメータを使用したくない場合があります。
サイボーグ

一部の古いbusyboxバージョンでdate -s @は、機能せず、awk引き続き機能します!stdinなしの例も役に立ちます。
Victor Sergienko 2017年

8

Bash 4.2以降では、printf%(datefmt)T形式を使用できます。

$ printf '%(%c)T\n' 1267619929
Wed 03 Mar 2010 01:38:49 PM CET

組み込みのシェルなので、これはすばらしいことです。datefmtの形式は、が受け入れる文字列ですstrftime(3)(を参照man 3 strftime)。ここに%cあります:

%c 現在のロケールの優先日時表現。


引数を受け入れるスクリプトが必要で、引数が指定されていない場合にstdinを読み取る場合は、次のように進めることができます。

#!/bin/bash

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

6

ログファイルを変換または監視するときに、これを使用します。

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

まさに私が探していたものに短縮することができますawk '{ printf strftime("%c: ", $1); $1 = ""; print $0; }'
ChrisWue

5

OSXまたはBSDに-rは、UNIXタイムスタンプをとる同等のフラグがあります。次に、日付を4回実行する例を示します。最初の日付に1回、それが何であるかを示します。1つは、を使用したUNIXタイムスタンプへの変換用%sで、最後に、を使用して-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

タイムスタンプ値がすでにあり、同等の日付を見つける必要がある場合は、OS Xでコマンドラインに次のように入力するだけです:date -r 1509453417
Noel Whitemore

1
それは本当だ。私の答えを見ると、私は実際にそれを実証しています。
ダニエルファレル

5

このようなタイムスタンプからフォーマットされた日付を取得できます

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

他の方法:date -ud "@ 1585667718" + '%Y-%m-%d%H:%M:%S'
AndiAna

3

これを自分で行うスクリプトを作成しました。

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

1
質問タグには「bash」が含まれていますが、シバンには「sh」と書かれています。
追って通知があるまで一時停止。

3

この回答では、Dennis Williamsonの回答をコピーして少し変更し、多数のタイムスタンプの列をスクリプトにパイプするときに大幅な速度向上を可能にします。たとえば、私のマシンでxargs -n1を使用して元のスクリプトに1000のタイムスタンプをパイプすると、変更されたバージョンでは0.027秒でしたが、6.929秒かかりました。

#!/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

2

いくつかの例:

$日付
2016年3月22日火曜日16:47:06 CST

$ date -d "2016年3月22日火曜日16:47:06 CST" "+%s"
1458636426

$日付+%s
1458636453

$日付-d @ 1458636426
2016年3月22日火曜日16:47:06 CST

$日付--date = '@ 1458636426'
2016年3月22日火曜日16:47:06 CST



2

私はこのクロスプラットフォームのワンライナーを使用します:

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

一般的なLinuxディストリビューションのmacOSとそれ以降のバージョンの両方で動作するはずです。


0

純粋なbashではありませんが、次のスクリプトは、文字列内の長さ13のタイムスタンプを、perlを使用してローカルタイムゾーンの同等の日付に変換します

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"}

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.