Nasıl zaman damgaları Bash tarihlere dönüştürmek için?


270

Bir kabuk komut veya Unix zaman damgası bir tarihe dönüştüren komut dosyası gerekir. Giriş, ilk parametre veya stdin'den gelebilir ve aşağıdaki kullanım şekillerine izin verir:

ts2date 1267619929

ve

echo 1267619929 | ts2date

Her iki komut da "Çar Mar 3 13:38:49 2010" çıktısını vermelidir.

Yanıtlar:


531

Yaygın Linux dağıtımlarının sonraki sürümlerinde şunları kullanabilirsiniz:

date -d @1267619929

5
One-liner:date -d @$(date -u +%s)
Mike Atlas

26
Ne @için? Bunu GNU kılavuz sayfasında hiç görmüyorum.
Mark E. Haase

13
@mehaase - man sayfası, tarih dizesinin manpage'de belgelenemeyecek kadar karmaşık olduğunu not eder, bu yüzden bilgi bölümünde açıklanmıştır: info '(coreutils) tarih çağrısı'
MByD

10
brew install coreutils; gdate -d @1267619929
Mark Fox

2
info 'Date input formats' sizi doğrudan dateilgili Robert Grudin alıntısıyla biçimlendiren bilgi düğümüne ve daha sonra bir biçim belirteçleri menüsüne götürür.
mike

165
date -r <number>

Mac OS X'te benim için çalışıyor.


5
Evet, ama bir saniyenin kesirlerini işlemiyor.
mgold

1
Ve kafa karıştırıcı çünkü çoğu linux sisteminde bu şekilde çalışmıyor, çünkü: freddy @ hades ~% date --help | grep - -r -r, --reference = FILE DOSYA'nın son değişiklik süresini göster
frank42

1
bu cevabın yorumları doğru olsa da, bunlar rafa'nın hatası değildir ve cevabını azaltmazlar.
mike

29

Bu sürüm chiborg'un cevabına benzer , ancak harici ttyve ihtiyacını ortadan kaldırır cat. Kullanır date, ancak aynı derecede kolayca kullanabilir gawk. Meseli değiştirebilir ve çift köşeli parantezleri tekli ile değiştirebilirsiniz ve bu da çalışacaktır 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: çok eksiksiz bir cevap ve tarihin gawk'den daha hızlı olduğunu düşünüyorum.
Bruno Brant

@Bruno, tarihin gawk'den daha hızlı olduğunu nereden biliyorsun?
ghostdog74

3
@Bruno, @ ghostdog74: Sistemimde, gawk(çok kabaca) date, foryalnızca çıkıştan yönlendirilen gawk 'BEGIN { print strftime("%c", 1256571985); }'veya date -d '@1256571985' +%cçıktı içeren bir zamanlanmış döngüden % 15 daha hızlı /dev/null.
sonraki duyuruya kadar duraklatıldı.

1
tarih marjinal olarak (% 5) benim için gawk'tan daha hızlı (mac osx 10.9.2, tarih 8.23, gawk 4.1.1), ancak (g) awk'nin gerçek avantajı, birçok zaman damgasının bir sütununun bir borusunu kabul etmektir (bkz. Aşağıdaki cevabım), betiği örneğin 1000 zaman damgası için 250x hızlı yapar.
webb

3
Cevabımın soruda belirtildiği gibi OP'nin gereksinimlerini karşıladığını, ancak şimdi kabul edilen cevabın karşılanmadığını unutmayın.
sonraki duyuruya kadar duraklatıldı.

17

GNU tarihini kullanabilirsiniz, örneğin,

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

veya

$ date -ud @1267619929

10

Bu basit awk betiğini kullanabilirsiniz:

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

Örnek kullanım:

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

Bu ilk kullanıma uymuyor - bazen TS'yi yankılamak ve bunun yerine bir parametre kullanmak istemiyorum.
chiborg

Bazı eski meşgul kutusu sürümünde, date -s @çalışmıyor ve awkhala çalışıyor ! Stdin içermeyen bir örnek de yardımcı olacaktır.
Victor Sergienko

8

Bash 4.2 yana kullanabilirsiniz printfs' %(datefmt)Tformatı:

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

Bu güzel, çünkü bir kabuk yerleşik. Datefmt biçimi tarafından kabul edilen bir dizedir strftime(3)(bkz. man 3 strftime). İşte %c:

%c Geçerli yerel ayar için tercih edilen tarih ve saat gösterimi.


Şimdi, bir argümanı kabul eden bir komut dosyası istiyorsanız ve hiçbiri sağlanmadıysa, stdin'i okursa şu şekilde devam edebilirsiniz:

#!/bin/bash

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

6

Günlük dosyalarını dönüştürürken veya izlerken bunu kullanıyorum:

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

tam olarak aradığım şey, kısaltılabilirawk '{ printf strftime("%c: ", $1); $1 = ""; print $0; }'
ChrisWue

5

OSX veya BSD'de, -rgörünüşe göre bir unix zaman damgası alan eşdeğer bir bayrak var. İşte tarihi dört kez çalıştıran bir örnek: ilk tarih için bir kez, ne olduğunu göstermek için; biri unix zaman damgasına dönüştürmek için %sve son olarak da, bir dizeye geri dönüşü sağlayan -rşeyi dönüştürü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

En azından makinemde çalışıyor gibi görünüyor.

$ 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

Zaten bir zaman damgası değeriniz varsa ve sadece eşdeğer tarihi bulmanız gerekiyorsa, OS X'te bunu komut satırına yazabilirsiniz: tarih -r 1509453417
Noel Whitemore

1
Bu doğru. Cevabıma bakarsanız, aslında bunu gösteriyorum.
Daniel Farrell

5

Bu şekilde zaman damgasından biçimlendirilmiş tarih alabilirsiniz

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

Diğer yol: tarih -ud "@ 1585667718" + '% Y-% m-% d% H:% M:% S'
AndiAna

3

Bunu kendim yapan bir senaryo yazdım:

#!/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
Soru etiketlerinizde "bash" var, ancak ibadetinizde "sh" yazıyor.
sonraki duyuruya kadar duraklatıldı.

3

Bu cevapta, Dennis Williamson'un cevabını kopyalarım ve betiğe birçok zaman damgası içeren bir sütunu bağlarken büyük bir hız artışı sağlamak için biraz değiştirdim. Örneğin, makinemdeki xargs -n1 ile orijinal komut dosyasına 1000 zaman damgası eklemek, bu değiştirilmiş sürümle 0.027'lerin aksine 6.929'ları aldı:

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

bazı örnek:

$ tarih
Sal 22 Mar 16:47:06 CST 2016

$ date -d "Sal 22 Mar 16:47:06 CST 2016" "+% s"
1458636426

$ tarih +% s
1458636453

$ date -d @ 1458636426
Sal 22 Mar 16:47:06 CST 2016

$ date --date = '@ 1458636426'
Sal 22 Mar 16:47:06 CST 2016



2

Bu çapraz platform tek astarını kullanıyorum:

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

Hem macOS hem de yaygın Linux dağıtımlarının sonraki sürümlerinde çalışmalıdır.


0

Saf bash olmasa da, aşağıdaki komut dosyası, bir dizede uzunluk 13 olan zaman damgalarını perl kullanarak yerel saat diliminizdeki eşdeğer tarihlerine dönüştürür

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"

giriş

{"timestamp":"1573121629939","level":"DEBUG","thread":"http-nio-15372-exec-3","logger":"org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor"}

çıktı

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

-8

PHP dilinde

$unix_time = 1256571985;

echo date("Y-m-d H:i:s",$unix_time)

5
Güzel, ama sadece bash kullanmak istedim.
chiborg
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.