2017-11-03 2 views
1

Ich habe versucht, mit dem Code unten, aber die CSV-Datei hat über 80 Millionen Zeilen (etwa 25 GB) und einige der Sonderzeichen scheinen zu brechen der echo-Befehl Der CSV hat 2 Spalten, die durch ein Komma getrennt sind. ex:Bash: Base64 kodiert 1 Spalte in einer sehr großen .csv und Ausgabe in neue Datei

blah, blah2 
data1,data2 
line3,fd$$#$%T%^Y%&$$B 
somedata,%^&%^&%^&^ 

Das Ziel ist, dass die zweite Säule zu nehmen und base64 ist bereit, um in eine SQL-Datenbank zu importieren. Ich mache eine Base64-Codierung für die zweite Spalte, also gibt es Unicode-Unterstützung usw. und kein Zeichen wird die Datenbank beschädigen. Ich bin auf der Suche nach einer effizienteren Art und Weise, dies zu tun, die auf Sonderzeichen nicht brechen usw.

awk -F "," ' 
    { 
     "echo "$2" | base64" | getline x 
     print $1, x 
    } 
' OFS=',' input.csv > base64.csv 

Fehler:

sh: 1: Syntax error: word unexpected (expecting ")") : 
not foundrf : 
not found201054 : 
not foundth : 
not foundz09 
| base64' (Too many open files)ut.csv FNR=1078) fatal: cannot open pipe `echo q1w2e3r4 
+0

ein anderes Problem im Finden ist die zweite Spalte kann ein Komma innerhalb der Daten auch enthalten sowieso um das zu umgehen – illwill

Antwort

1

Das Problem ist, dass Sie zitieren das Argument zu echo in der awk Skript.

Aber es gibt keine Notwendigkeit, awk dafür zu verwenden, bash kann die Datei direkt analysieren.

IFS=, while read -r col1 col2 
do 
    base64=$(base64 <<<"$col2") 
    echo "$col1, $base64" 
done <input.csv> base64.csv 
+0

erhalten Fehler: ./base64.sh: Zeile 2: während: Befehl nicht gefunden ./ base64.sh: Zeile 3: Syntaxfehler in der Nähe des unerwarteten Tokens 'do ' ./base64.sh: Zeile 3:' do' – illwill

+0

Ich kann mir keinen Grund vorstellen, warum es den 'while' Befehl nicht finden könnte, es ist ein eingebauter Befehl. – Barmar

+0

Wenn ich nach anderen Beispielen für diesen Fehler suche, sind sie immer auf eine Art Tippfehler zurückzuführen. – Barmar

0

The goal is to take that second column and base64

Mit awkgetline Funktion:

awk -F',[[:space:]]*' '{ cmd="echo \042"$2"\042 | base64"; cmd | getline v; 
     close(cmd); print $1","v }' input.csv > base64.csv 

Die base64.csv Inhalte (für Stromeingang):

blah,YmxhaDIK 
data1,ZGF0YTIK 
line3,ZmQyNzMwOCMkJVQlXlklJjI3MzA4Qgo= 
somedata,JV4mJV4mJV4mXgo= 
+0

Ich war nicht klar, dass die Ausgabe col1, col2 als col1, base64col2 ausgegeben werden soll. youres Ausgänge nur die base64'd zweite Spalte nur – illwill

+0

@illwill finden Sie in meinem Update – RomanPerekhrest

0

Versuchen Sie so etwas in Ihrer MySQL-Kommando- Linienkunde:

LOAD DATA LOCAL '/tmp/filename.txt' INTO TABLE tbl FIELDS TERMINATED BY ','

Sie können Felder neu anordnen, wenn nötig und spezielle Ausdrücke gelten, wenn Sie Sonderzeichen entfernen müssen, Strings verketten, Datumsformat konvertieren, etc. Wenn Sie noch wirklich base64 Konvertierung benötigen, MySQL-Versionen 5.6 und später haben eine native Funktion dafür (TO_BASE64()), während es für die älteren eine UDF gibt. Siehe base64 encode in MySQL

jedoch solange Ihre Spalten keine Kommas haben, LOAD DATA INFILE wird es handhaben können, und Sie können durch die Vermeidung der Umwandlung etwas Speicherplatz sparen.

Einzelheiten dazu, wie LOAD DATA INFILE Verwendung finden Sie MySQL-Handbuch: https://dev.mysql.com/doc/refman/5.7/en/load-data.html

Sie müssen MySQL als Benutzer mit dem LOAD Privileg authentifizieren und haben local-infile Option aktiviert (zB durch --local-infile=1 auf die Weitergabe

+0

wie gut funktioniert diese Arbeit mit großen Datensätzen mit dem Eingang und Umbauten bis Overhead etc. – illwill

+0

Der Aufwand ungefähr so ​​niedrig ist, wie Sie vielleicht machen könnte, ohne Schreiben Sie Ihren eigenen maßgeschneiderten Eingabe-Converter in C. Praktisch können Sie es kaum in einem Benchmark messen, wenn es nicht sehr kompliziert ist. Abgesehen davon, dass Sie Ihren eigenen maßgeschneiderten Low-Level-Tablespace-Importer implementieren, können Sie ihn mit nichts anderem übertreffen. –

Verwandte Themen