2012-11-22 5 views
5

Sto utilizzando l'editor di flusso sed per convertire un grande insieme di dati di file di testo (400 MB) in un formato CSV.sed - rimuovere le virgolette tra virgolette in file CSV di grandi dimensioni

Sono venuto molto vicino a finire, ma il problema in sospeso sono le citazioni all'interno di citazioni, su un dato come questo:

1,word1,"description for word1","another text",""text contains "double quotes" some more text" 
2,word2,"description for word2","another text","text may not contain double quotes, but may contain commas ," 
3,word3,"description for "word3"","another text","more text and more" 

L'output desiderato è:

1,word1,"description for word1","another text","text contains double quotes some more text" 
2,word2,"description for word2","another text","text may not contain double quotes, but may contain commas ," 
3,word3,"description for word3","another text","more text and more" 

Ho cercato in giro per aiuto, ma non mi sto avvicinando troppo alla soluzione, ho provato i seguenti sed con modelli regex:

sed -i 's/(?<!^\s*|,)""(?!,""|\s*$)//g' *.txt 
sed -i 's/(?<=[^,])"(?=[^,])//g' *.txt 

Queste sono le domande che seguono, ma non sembrano lavorare per sed:

Related question for perl

Related question for SISS

I file originali sono * .txt e sto cercando di modificare al loro posto con sed.

+0

Qual è l'output desiderato? –

+0

L'ho aggiornato, grazie. – nol

risposta

2

Ecco un modo utilizzando GNU awk e il FPAT variabile:

gawk 'BEGIN { FPAT="([^,]+)|(\"[^\"]+\")"; OFS=","; N="\"" } { for (i=1;i<=NF;i++) if ($i ~ /^\".*\"$/) { gsub(/\"/,"", $i); $i=N $i N } }1' file 

Risultati:

1,word1,"description for word1","another text","text contains double 
quotes some more text" 2,word2,"description for word2","another 
text","text may not contain double quotes, but may contain commas ," 
3,word3,"description for word3","another text","more text and more" 

Spiegazione:

Utilizzando FPAT, un campo è definito come "qualsiasi cosa che non è una virgola "o" una virgola doppia, tutto ciò che non è una doppia qu ote e una doppia virgoletta di chiusura ". Quindi su ogni riga di input, passa attraverso ciascun campo e se il campo inizia e termina con una virgoletta doppia, rimuovere tutte le virgolette dal campo. Infine, aggiungi le doppie virgolette che circondano il campo .

+0

@alinsoar, grazie a entrambi. Alla fine, la risposta di Steve mi ha aiutato a finire con un risultato migliore anche se non era sed. – nol

+0

Questa soluzione non funziona su Mac OSX Shell (Sierra) –

+0

@RiccardoDonato: Stai usando 'gawk' (GNU AWK)?' FPAT' è specifico 'gawk'. – Steve

1
sed -e ':r s:["]\([^",]*\)["]\([^",]*\)["]\([^",]*\)["]:"\1\2\3":; tr' FILE 

questo sembra sulle corde del tipo "STR1 "STR2" STR3 " e li converte in "STR1 STR2 STR3". Se trova qualcosa, si ripete, per essere sicuro che elimina tutte le stringhe nidificate a una profondità> 2.

Inoltre, nessuno di STRx contiene comma.

+0

grazie, questo è quasi arrivato, sto ottenendo '1, parola1," descrizione per parola1 "," altro testo "," testo contiene virgolette "un po 'più testo" 'nella prima riga però. Ti dispiacerebbe anche spiegarti cosa fa il \ 1 \ 2 \ 3? – nol

Problemi correlati