Datum in CSV-Tabelle in Unix-Zeitstempel umformatieren

Datum in CSV-Tabelle in Unix-Zeitstempel umformatieren

Ich habe eine .csvDatei, die Datum und Uhrzeit in 01/20/2016 23:53:01der ersten Spalte im Format enthält. Meine Spalten sind durch Semikolons getrennt, d. h.

01/21/2016 03:03:01;18616;0;1
01/21/2016 03:13:01;29040;36553;2

AnALSOIch habe den Bash-Befehl gefunden

date -d '06/12/2012 07:21:22' +"%s" 

das funktioniert für das, was ich will. Ich habe jetzt versucht, mit zu integrieren, awkum die erste Spalte zu ersetzen. Ich habe eine gefundenAntwort auf ein ähnliches Problem:

awk -F'"' -v OFS='"'  '$8 {cmd="date -d \""$8"\" +%FT%T%z"; cmd | getline $8; close(cmd)} 1' input.json

Ich habe versucht, es an meine eigenen Eingaben anzupassen. Aber ich habe eine leere Ausgabe erhalten.

Antwort1

Beim Schreiben der Frage habe ich es endlich geschafft. Hier ist also meine Lösung:

awk -F';' -v OFS=';'  '$1 {cmd="date -d \""$1"\" +%s"; cmd | getline $1; close(cmd)} 1' datetime.csv > unix.csv

Es war die Kombination aus zwei Dingen: Mir hatte das "„Ein“ gefehlt +%s"und in meiner Eingabe war die Zeile defekt.

Antwort2

GNU date bietet eine -fOption, um aus einer Datei gelesene Daten Zeile für Zeile umzuwandeln. Wenn Ihre Datei lang ist, ist dies schneller, als wenn Sie es dateeinmal pro Zeile aufrufen. Das Datum muss allein in der Zeile stehen; daher besteht der Plan darin, die erste Spalte zu isolieren ( cut -d \; -f 1), diese durchlaufen zu lassen, date -f -um die Umwandlung durchzuführen, undPastedas Ergebnis mit den restlichen Spalten.

paste -d \; <(<input cut -d \; -f 1 | date -f - +%s) <(<input cut -d \; -f 2-)

Dies setzt voraus, dass Ihre Shell unterstütztProzesssubstitution(ksh93, bash, zsh). Mit plain können Sie shauf einer Unix-Variante, die dies unterstützt /dev/fd(die meisten tun es), File-Descriptor-Shuffling verwenden:

<input cut -d \; -f 2- | {
  exec 3<&0
  <input cut -d \; -f 1 | date -f - +%s | paste -d \; - /dev/fd/3
}

Antwort3

Hmmmm. Okay, das ist schon eine Weile her, aber ich dachte, ich könnte auch mal einen Vorschlag machen.

Ich bin ziemlich sicher, dass der Aufruf von „date“ für jede Zeile Ihrer Datei in der Shell etwas langsam sein kann, wenn Sie viele Zeilen haben.

Ich wollte ein Skript aufrufen, das ich geschrieben habe, um Zeiterfassungseinträge zu verarbeiten, die ich aus Google Kalender extrahiert habe, und HTML ausgeben, um sie dann in eine PDF-Rechnung umzuwandeln. Aber dann wurde es zu lange, darüber zu reden. Deshalb gebe ich Ihnen einfach den Code, damit Sie sich das Lesen sparen.

Ich verwende die AWK-Funktionen gensub und mktime [https://www.gnu.org/software/gawk/manual/html_node/Time-Functions.html]. Die Funktion mktime erwartet die Eingabe im Datumsformat „JJJJ MM TT HH MM SS [DST]“, daher muss Ihre Eingabe verschoben werden, und hier kommt die Funktion gensub ins Spiel. Hier ist, was ich für Sie habe …

awk -F';' -v OFS=';' '{ $1=mktime(gensub(/(..)\/(..)\/(....) (..):(..):(..)/, "\\3 \\1 \\2 \\4 \\5 \\6", 1, $1)); } 1' datetime.csv > unix.csv

Ich würde das etwas anders machen und die einzelnen Argumente in einem Print ausgeben, anstatt auf das erste Argument zurückzuschreiben. Ein klein wenig selbstdokumentierender ;) ZEITSCHRIFT

awk -F';' -v OFS=';' '{ print mktime(gensub(/(..)\/(..)\/(....) (..):(..):(..)/, "\\3 \\1 \\2 \\4 \\5 \\6", 1, $1)), $2, $3, $4; }' datetime.csv > unix.csv

Ich weiß, dass das Skript etwas ausführlicher ist, aber hoffentlich ist es leistungsfähiger.

Ich hoffe, das hilft Ihnen oder anderen, die dasselbe betrachten.

verwandte Informationen