2017-02-05 3 views
3

Ich habe eine Bash Frage (bei der Verwendung von awk). Ich bin jede einzelne Instanz der ersten und der fünften Spalte in einer Text-Datei zu extrahieren und sie in eine neue Datei mit dem folgenden Code kochend,Umwandlung von Datum zu Epoche

cut -f4 test170201.rawtxt | awk '/stream_0/ { print $1, $5 }' > testLogFile.txt 

Dieser Teil der Datei ist (test170201.rawtxt) Ich bin Extrahieren die Daten aus, Spalten Timestamp und Loss,

Timestamp     Stream  Status  Seq   Loss Bytes Delay 
17/02/01.10:58:25.212577 stream_0  OK  80281   0 1000  38473 
17/02/01.10:58:25.213401 stream_0  OK  80282   0 1000  38472 
17/02/01.10:58:25.215560 stream_0  OK  80283   0 1000  38473 
17/02/01.10:58:25.216645 stream_0  OK  80284   0 1000  38472 

Dies ist das Ergebnis bin ich

17/02/01.10:58:25.212577 0 
17/02/01.10:58:25.213401 0 
17/02/01.10:58:25.215560 0 
17/02/01.10:58:25.216645 0 

jedoch in testLogFile.txt bekommen, möchte ich die 01.230.in der obigen Datei in Epoche geschrieben werden. Gibt es eine einfache Möglichkeit, den Code zu ändern, den ich bereits dafür habe?

Antwort

3

Gegeben:

$ cat file 
Timestamp     Stream  Status  Seq   Loss Bytes Delay 
17/02/01.10:58:25.212577 stream_0  OK  80281   0 1000  38473 
17/02/01.10:58:25.213401 stream_0  OK  80282   0 1000  38472 
17/02/01.10:58:25.215560 stream_0  OK  80283   0 1000  38473 
17/02/01.10:58:25.216645 stream_0  OK  80284   0 1000  38472 

Sie ein POSIX-Bash-Skript schreiben können, zu tun, was Sie suchen:

while IFS= read -r line || [[ -n "$line" ]]; do 
    if [[ "$line" =~ ^[[:digit:]]{2}/[[:digit:]]{2}/[[:digit:]]{2} ]] 
    then 
     arr=($line) 
     ts=${arr[0]} 
     dec=${ts##*.} # fractional seconds 
     # GNU date may need different flags: 
     epoch=$(date -j -f "%y/%m/%d.%H:%M:%S" "${ts%.*}" "+%s") 
     printf "%s.%s\t%s\n" "$epoch" "$dec" "${arr[4]}" 
    fi 
    done <file >out_file 

$ cat out_file 
1485975505.212577 0 
1485975505.213401 0 
1485975505.215560 0 
1485975505.216645 0 

Für GNU Datum, versuchen:

while IFS= read -r line || [[ -n "$line" ]]; do 
    if [[ "$line" =~ ^[[:digit:]]{2}/[[:digit:]]{2}/[[:digit:]]{2} ]] 
    then 
     arr=($line) 
     ts="20${arr[0]}" 
     d="${ts%%.*}" 
     tmp="${ts%.*}" 
     tm="${tmp#*.}" 
     dec="${ts##*.}" # fractional seconds 
     epoch=$(date +"%s" --date="$d $tm") 
     printf "%s.%s\t%s\n" "$epoch" "$dec" "${arr[4]}" 
    fi 
    done <file >out_file 

Für ein GNU awk Lösung können Sie tun:

awk 'function epoch(s){ 
         split(s, dt, /[/:. ]/) 
         s="20" dt[1] " " dt[2] " " dt[3] " " dt[4] " " dt[5] " " dt[6] 
         return mktime(s) "." dt[7]} 
    /^[0-9][0-9]/  { print epoch($1), $5 }' file >out_file 

Wenn Sie in der Epoche enthalten nicht die Sekundenbruchteile wollen, werden sie leicht entfernt werden.

+0

Ich habe versucht, Ihre Lösung, aber ich erhielt den folgenden Fehler Versuchen Sie 'date --help 'für weitere Informationen. Datum: ungültige Option - 'j'. Irgendeine Idee, was das Problem sein könnte? – user3325598

+0

Wie in den Kommentaren angegeben: * GNU-Datum benötigt möglicherweise andere Flags * Ich habe nur BSD, also kann die GNU-Version nicht testen. Das Flag '-j' weist POSIX' date' an, das Systemdatum nicht zu setzen. Ich denke du kannst einfach für [GNU date] entfernen (http://man7.org/linux/man-pages/man1/date.1.html). – dawg

+0

Ich habe das Flag -j entfernt, aber einen neuen Fehler erhalten, Datum: Extra Operand '+% s ' – user3325598

0

Mit GNUawk

Eingang

$ cat f 
Timestamp     Stream  Status  Seq   Loss Bytes Delay 
17/02/01.10:58:25.212577 stream_0  OK  80281   0 1000  38473 
17/02/01.10:58:25.213401 stream_0  OK  80282   0 1000  38472 
17/02/01.10:58:25.215560 stream_0  OK  80283   0 1000  38473 
17/02/01.10:58:25.216645 stream_0  OK  80284   0 1000  38472 

Ausgabe

$ awk ' 
BEGIN{cyear = strftime("%y",systime())} 
function epoch(v,  datetime){ 
    sub(/\./," ",v); 
    split(v,datetime,/[/: ]/); 
    datetime[1] = datetime[1] <= cyear ? 2000+datetime[1] : 1900+datetime[1]; 
    return mktime(datetime[1] " " datetime[2] " " datetime[3] " " datetime[4]" " datetime[5]" " datetime[6]) 
} 
/stream_0/{ 
    print epoch($1),$5 
}' f 



1485926905 0 
1485926905 0 
1485926905 0 
1485926905 0 

neue Datei zu schreiben, wie umleiten unten

cut -f4 test170201.rawtxt | awk ' 
BEGIN{cyear = strftime("%y",systime());} 
function epoch(v,  datetime){ 
    sub(/\./," ",v); 
    split(v,datetime,/[/: ]/); 
    datetime[1] = datetime[1] <= cyear ? 2000+datetime[1] : 1900+datetime[1]; 
    return mktime(datetime[1] " " datetime[2] " " datetime[3] " " datetime[4]" " datetime[5]" " datetime[6]) 
} 
/stream_0/{ 
    print epoch($1),$5 
}' > testLogFile.txt 
+0

Das scheint die falsche [Epoche] zu sein (htt p: //www.epochconverter.com) – dawg

+0

Erstellt diese Lösung eine Datei mit den zwei Spalten oder druckt sie nur? – user3325598

+0

@dawg: Korrigiert, Problem war, dass der Requester nicht erwähnt hat, ob das Datumsformat 'd-m-y' oder' y-m-d' jetzt geändert wurde –

1
awk -F '[.[:blank:]]+' ' 
    # use separator for dot and space (to avoid trailing time info) 

    { 
    # for line other than header 
    if(NR>1) { 
     # time is set for format "YYYY MM DD HH MM SS [DST]" 
     # prepare with valuable info 
     T = "20"$1 " " $2 
     # use correct separator 
     gsub(/[\/:]/, " ", T) 
     # convert to epoch 
     E = mktime(T) 

     # print result, adding fractionnal as mentionned later 
     printf("%d.%d %s\n", E, $3, $7) 
     } 
    else { 
     # print header (line 1) 
     print $1 " "$7 
     } 
    } 
    ' test170201.rawtxt \ 
    > Redirected.file 
  • selbst kommentierte Code ist mehr für einen bestimmten Zweck zu verstehen
  • Verwendung von Gnu awk für die Mktime Funktion nicht verfügbar in Posix oder ältere Version

Oneliner ein bisschen hier optimiert nach

awk -F '[.[:blank:]]+' '{if(NR>1){T="20"$1" "$2;gsub(/[\/:]/," ", T);$1=mktime(T)}print $1" "$7}' test170201.rawtxt 
+0

Aber ich möchte immer noch eine Datei der Ausgabe machen, könnten Sie Ihre Lösung aktualisieren? – user3325598

+0

hinzugefügt die Fracitonal + Umleitung als Anfrage nach – NeronLeVelu