11 Stimmen

Verwenden Sie sed oder awk, um das Datumsformat zu korrigieren

Ich versuche, eine HTML-Datei mit einer Tabelle mithilfe eines bash-Skripts in eine .csv-Datei umzuwandeln.

Bisher habe ich die folgenden Schritte abgeschlossen:

  1. In Unix-Format konvertieren (mit dos2unix)
  2. Alle Leerzeichen und Tabs entfernen (mit sed 's/[ \t]//g')
  3. Alle leeren Zeilen entfernen (mit sed ':a;N;$!ba;s/\n//g') (das ist notwendig, da die HTML-Datei für jede Zelle der Tabelle eine leere Zeile hat... das ist nicht meine Schuld)
  4. Die unnötigen und Tags entfernen (mit sed 's///g')
  5. durch ',' ersetzen (mit sed 's/<\/td/,/g')
  6. durch Zeilenumbrüche (\n) ersetzen (mit sed 's/<\/tr/\n/g')

Natürlich führe ich all dies in einer Pipeline aus. Bisher funktioniert es gut. Es gibt einen letzten Schritt, bei dem ich stecken geblieben bin: Die Tabelle enthält eine Spalte mit Datumsangaben im Format dd/mm/yyyy, und ich möchte sie in yyyy-mm-dd umwandeln.

Gibt es einen (einfachen) Weg, dies zu tun (mit sed oder awk)?

Datenbeispiel (nach dem gesamten sed-Befehl):

500,2,13/09/2007,30000.00,12,B-1
501,2,15/09/2007,14000.00,8,B-2

Ergebnis:

500,2,2007-09-13,30000.00,12,B-1
501,2,2007-09-15,14000.00,8,B-2

Der Grund, warum ich das tun muss, ist, dass ich diese Daten in MySQL importieren muss. Ich könnte die Datei in Excel öffnen und das Format manuell ändern, aber ich würde das gerne überspringen.

12voto

ash Punkte 4727
sed -E 's,([0-9]{2})/([0-9]{2})/([0-9]{4}),\3-\2-\1,g'

11voto

Birei Punkte 34938

Awk kann diese Aufgabe ziemlich einfach erledigen:

awk '
    BEGIN { FS = OFS = "," } 
    { split($3, date, /\//)
      $3 = date[3] "-" date[2] "-" date[1]
      print $0 
    }
' infile

Es liefert:

500,2,2007-09-13,30000.00,12,B-1
501,2,2007-09-15,14000.00,8,B-2

6voto

lurker Punkte 55527
sed "s:,\([0-9]\+\)/\([0-9]\+\)/\([0-9]\+\),:,\3-\2-\1,:"

5voto

twalberg Punkte 56757

awk würde hierfür funktionieren:

echo 26.08.2013 | awk -F/ '{printf "%s-%s-%s\n",$3,$2,$1}'

ebenso wie eine dieser nur von bash unterstützten Optionen:

IFS=/ read m d y < <(echo 26.08.2013); echo "${y}-${m}-${d}"
IFS=/ read m d y <<< "26.08.2013"; echo "${y}-${m}-${d}"

Wenn Sie zufällig ksh verwenden, wo für das letzte Element einer Pipeline kein Subshell verwendet wird, sollte dies ebenfalls funktionieren:

echo 26.08.2013 | IFS=/ read m d y; echo "${y}-${m}-${d}"

In neueren bash-Versionen können Sie auch shopt -s lastpipe in einem Skript verwenden, um die oben genannte Aufrufmethode ebenfalls zu ermöglichen, es funktioniert jedoch nicht auf der Befehlszeile (dank @mklement0 in den Kommentaren unten).

Ich überlasse es Ihnen, herauszufinden, wie Sie es mit dem Rest integrieren können...

4voto

Bisher sind alle Antworten sehr spezifisch für das Problem des Fragestellers. Hier ist ein allgemeinerer Ansatz, der (für die -d-Option) date durch awk ausführt:

awk 'BEGIN{FS=","}
     {
       "date -d\"" $3 "\" +%Y-%m-%d" | getline mydate; 
       print $1 "," $2 "," mydate "," $4 "," $5 "," $6
     }'

Natürlich funktioniert dieser Ansatz nur, wenn das Eingabedatumsformat von date verarbeitet wird. Nach meinem Kenntnisstand ist dies leider nicht der Fall für dd/mm/yyyy. Möglicherweise kann man andere Befehle als date ausprobieren (nicht getestet).

Bearbeitung: mklement0's Kommentar implementiert.

Bearbeitung2: Tatsächlich funktioniert dies nicht mit mawk, was die Standard-awk-Implementierung von Debian ist. Die offensichtliche Lösung ist die Installation von gawk, wenn möglich.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X