2016-11-01 11 views
0

Ich habe eine Sehr große (13 GiB) CSV-Datei (3856321 Zeilen und 1698), wo wie erwartet einige der Daten anders formatiert sind. Die Datei sieht aus wie ::Formatieren und Konvertieren von Datum und Uhrzeit

2013/01/08 2:11:30 AM,abdc,good time ... 
2015/12/28 8:19:30 PM,abdc,good time ... 
2/15/2016 10:46:30 AM,kdafh,almost as good ... 
12/13/2014 10:46:00 PM,asjhdk,not that good ... 
02-Jan-2014,bad time,good time ... 
1/1/2015,nomiss time,boy ... 
10/15/2016 17:08:30,bad,boy ... 

ich es zu einem gleichen Zeit Format konvertieren wollen, und erforderliche Ausgabe ist ::

1/8/2013 2:11:30,abdc,good time 
12/28/2015 20:19:30,abdc,good time 
2/15/2016 10:46:30,kdafh,almost as good 
12/13/2014 22:46:00,asjhdk,not that good 
1/2/2014 00:00:00,bad time,good time 
1/1/2015 00:00:00,nomiss time,boy 
10/15/2016 17:08:30,bad,boy 

ich die Zeit mit Hilfe der folgenden Skripte zu formatieren verwaltet

awk -F ',' 'BEGIN{FS=OFS=","}{split($1,a," "); 
if(a[3]=="PM") 
{ split(a[2],b,":"); 
    b[1]=b[1]+12  
    a[2]=b[1]":"b[2]":"b[3] 
}; 
if(a[2]=="") 
{ 
     a[2]="00:00:00" 
} 
tmp=a[1]; 
# tmp2=system("date -d `tmp` +%m/%d/%Y"); 
# print tmp2 
$1=tmp" "a[2] 
}1' time_input.csv 

Ich borgte die Idee der Formatierung von Daten aus Frage https://unix.stackexchange.com/questions/177888/how-to-convert-date-format-in-file , die in der vorletzten Zeile auskommentiert ist. Dies funktioniert jedoch in meinem Fall nicht. Ich erhalte einen Fehler

date: invalid date ‘+%m/%d/%Y’ 

Gibt es einen einfacheren und besseren Weg, dies zu tun? Vielen Dank im Voraus

Antwort

1

Mit Python, mit den dateutils und csv Module:

import dateutil.parser as parser 
import csv 

with open('time_input.csv', 'rb') as inputfile, open('time_output.csv', 'w') as outputfile: 

    reader = csv.reader(inputfile, delimiter=',') 
    writer = csv.writer(outputfile) 

    for row in reader: 
    row[0] = parser.parse(row[0]).strftime('%m/%d/%Y %H:%M:%S') 
    writer.writerow(row) 

Das Ergebnis wird auf time_output.csv Datei.

1

Awk ist sicher ein guter Weg, es zu tun, aber da es wirklich am frühen Morgen ist hier ich nicht diejenigen denken, wie alles über if sind so hier ist ein in PHP, da es eine wirklich schöne strtotime Funktion bekam ist :

$ cat program.php 
<?php 
    $handle = fopen("file", "r"); 
    if ($handle) { 
    while (($line = fgets($handle)) !== false) { 
     // process the line read. 

     $arr = explode(",", $line, 2);      
     echo date("m/d/Y H:i:s", strtotime($arr[0])), ",", $arr[1]; 

    } 
    fclose($handle); 
    } else { 
    // error opening the file. 
} 

Run it:

$ php -f program.php 
01/08/2013 02:11:30,abdc,good time 
12/28/2015 20:19:30,abdc,good time 
02/15/2016 10:46:30,kdafh,almost as good 
12/13/2014 22:46:00,asjhdk,not that good 
01/02/2014 00:00:00,bad time,good time 
01/01/2015 00:00:00,nomiss time,boy 
10/15/2016 17:08:30,bad,boy 

Die Lesezeilen Schleife kommt von hier: How to read a file line by line in php. Ich fügte nur Linien mit explode und strtotime hinzu.

Die explode teilt die Linie in Stücke durch die erste , und speichert sie in Array $arr. strtotime Funktion wird auf das erste Element $arr[0] angewendet. $arr[1] wird später so wie es ist ausgegeben.

+0

Danke! Obwohl es das tut, wonach ich gefragt habe, akzeptiere ich das obige Python-Beispiel, weil das für größere Dateien etwas schneller schien. Vielen Dank! – discipulus

1

Sie können unter awk Befehl versuchen -

Eingang

[email protected]:~$ cat kk.txt 
2013/01/08 2:11:30 AM,abdc,good time 
2015/12/28 8:19:30 PM,abdc,good time 
2/15/2016 10:46:30 AM,kdafh,almost as good 
12/13/2014 10:46:00 PM,asjhdk,not that good 
02-Jan-2014,bad time,good time 
1/1/2015,nomiss time,boy 
10/15/2016 17:08:30,bad,boy 

Filterung -

[email protected]:~$ awk -F"," '{split($1,a," "); printf ("%s,%s,%s",$2,$3,",");system("date -d \""a[1]" "a[2]"\" +\"%m/%d/%Y %H:%M:%S\"")}' kk.txt 
abdc,good time,,01/08/2013 02:11:30 
abdc,good time,,12/28/2015 08:19:30 
kdafh,almost as good,,02/15/2016 10:46:30 
asjhdk,not that good,,12/13/2014 10:46:00 
bad time,good time,,01/02/2014 00:00:00 
nomiss time,boy,,01/01/2015 00:00:00 
bad,boy,,10/15/2016 17:08:30 

Verschieben Sie die gefilterte Ausgabe in die Datei kk.txt2

[email protected]:~$ awk -F"," '{split($1,a," "); printf ("%s,%s,%s",$2,$3,",");system("date -d \""a[1]" "a[2]"\" +\"%m/%d/%Y %H:%M:%S\"")}' kk.txt > kk.txt2 

Ausgabe

[email protected]:~$ awk -F"," '{print $NF,$1,$2}' OFS="," kk.txt2 
01/08/2013 02:11:30,abdc,good time 
12/28/2015 08:19:30,abdc,good time 
02/15/2016 10:46:30,kdafh,almost as good 
12/13/2014 10:46:00,asjhdk,not that good 
01/02/2014 00:00:00,bad time,good time 
01/01/2015 00:00:00,nomiss time,boy 
10/15/2016 17:08:30,bad,boy 

Erklärung -

Verwenden Split Funktion auf Spalte 1 und es in ein setzen und verwenden dann system Funktion awk, um das Datum nach unserem Bedarf zu formatieren.

Ich kann die Ausgabe in der Reihenfolge drucken, aber es war eine führende Null drucken, so drucke ich formatiert Datum in der letzten Spalte, deshalb verschiebe ich die Daten in einer anderen Datei. und schließlich können Sie die Spalte in Ihrer Bestellung ausdrucken.

+0

Danke! Da hatte ich mehrere Spalten (> 1500, die ich in meiner Frage nicht erwähnt habe, Entschuldigung). Dieser Ausdruck würde nicht sehr gut funktionieren, aber ich hatte die Idee, das Datum in awk mit dynamischen Variablen zu verwenden. Da die obige Python-Idee einfacher war, akzeptiere ich das – discipulus

Verwandte Themen