So konvertieren Sie das Datumsformat in einer Datei

So konvertieren Sie das Datumsformat in einer Datei

Eingabedatei:Enthält 3 Spalten, wobei die 3. Spalte das Datum im DD-MMM-YYYYBeispieldatenformat enthält
:

1232,abdc, 02-Jan-2014
4534,kdafh, 20-Feb-2014
364,asjhdk, 11-Jul-2012

Benötigte Ausgabe:

1232,abdc, 2014-01-02
4534,kdafh, 2014-02-20
364,asjhdk, 2012-07-11

Funktion „Datum“ wird verwendet: date -d 20-DEC-2014 +%Y-%m-%d
Bei Verwendung des Awk-Befehls tritt ein Fehler auf
. Gibt es eine andere Möglichkeit?

Antwort1

Eine mögliche Antwort mit awk, vorausgesetzt, die Eingabedatei ist input-file.txt und die Ausgabedatei ist output-file.txt:

awk -F ',' '{printf("%s,%s,",$1,$2);system("date -d "$3" +%Y-%m-%d");}' input-file.txt > output-file.txt

Antwort2

Verwenden vonMüller( mlr), um die überzähligen Leerzeichen in der CSV-Eingabe ohne Header zu bereinigen und dann das 3. Feld neu zu schreiben. Das 3. Feld wird neu geschrieben, indem das angegebene Datum strptime()mit der Zeitformatzeichenfolge analysiert und dann der resultierende Unix-Zeitstempel mit und der Formatierungszeichenfolge %d-%b-%Yneu formatiert wird (Sie könnten beispielsweise anstelle von verwenden ):strftime()%F%Y-%m-%d%F

mlr --csv -N \
    clean-whitespace then \
    put '$3 = strftime(strptime($3,"%d-%b-%Y"),"%F")' file

Angesichts der Daten in der Frage würde dies ergeben:

1232,abdc,2014-01-02
4534,kdafh,2014-02-20
364,asjhdk,2012-07-11

strptime()Wenn Ihre Daten einen Zeitstempel im selben Feld haben, können Sie die in den - und -Aufrufen verwendeten Formatzeichenfolgen strftime()Ihren Anforderungen entsprechend anpassen.

strftimeWas diese Formatierungszeichenfolgen bedeuten und welche Möglichkeiten Sie zum Formatieren von Datum und Uhrzeit haben, erfahren Sie im Handbuch zu Ihrem System.

Antwort3

Angenommen, Ihr eingegebener Text sieht wie folgt aus:

1232,abdc, 02-Jan-2014 18:01:37</br> 
4534,kdafh, 20-Feb-2014 07:17:19</br>
364,asjhdk, 11-Jul-2012 23:20:30</br>

meine Antwort wäre:

cat input-file.txt | sed 's[</br>[[g' | awk -F ',' '{printf("%s,%s,",$1,$2);system("date -d \""$3" "$4"\" +\"%Y-%m-%d %H:%M:%S\"");}' > output-file.txt

Und wenn die Datensätze in einer einzigen Zeile stehen (keine neue Zeile in der Eingabedatei nach dem </br>), wäre es

cat input-file.txt | sed 's[</br>[\n[g' | awk -F ',' '{printf("%s,%s,",$1,$2);system("date -d \""$3" "$4"\" +\"%Y-%m-%d %H:%M:%S\"");}' > output-file.txt

Antwort4

Sie möchten keinen neuen Prozess erstellen, der für jede Zeile einer Datei eine Shell und einen weiteren Befehl ausführt. Das wäre sehr ineffizient. Wenn eine Shell Code basierend auf der Eingabe interpretiert, ist dies auch ein Rezept für die Einführung von Schwachstellen bei der Befehlsinjektion. Darüber hinaus -dist diese Option nicht standardmäßig.

Hier würde ich ein Textverarbeitungstool verwenden, das Zeitmanipulationen durchführen kann, wie z. B. Perl:

perl -MTime::Piece -pe '
  s{\d+-\w+-\d+$}{Time::Piece->strptime($&, "%d-%b-%Y")->ymd}e
  ' < your-file

Dort gleichen wir das <digits>-<word-characters>-<digits>am Ende der Zeile ( $) gefundene Element ab, interpretieren es als <day>-<month-abbrev>-<year>und formatieren es neu, als <yead>-<month>-<day>würde das Time::Piece-Modul des Perl-Kerns verwendet.

verwandte Informationen