2009-12-29 6 views
11

Ho scritto uno script che pulisce i file .csv, rimuovendo alcune cattive virgole e virgolette cattivi (cattivi, significa che rompono un programma in casa che utilizziamo per trasformare questi file) utilizzando sed:Perché il mio script Bash aggiunge <feff> all'inizio dei file?

# remove all commas, and re-insert the good commas using clean.sed 
sed -f clean.sed $1 > $1.1st 

# remove all quotes 
sed 's/\"//g' $1.1st > $1.tmp 

# add the good quotes around good commas 
sed 's/\,/\"\,\"/g' $1.tmp > $1.tmp1 

# add leading quotes 
sed 's/^/\"/' $1.tmp1 > $1.tmp2 

# add trailing quotes 
sed 's/$/\"/' $1.tmp2 > $1.tmp3 

# remove utf characters 
sed 's/<feff>//' $1.tmp3 > $1.tmp4 

# replace original file with new stripped version and delete .tmp files 
cp -rf $1.tmp4 quotes_$1 

Qui è clean.sed:

s/\",\"/XXX/g; 
:a 
s/,//g 
ta 
s/XXX/\",\"/g; 

Poi si rimuove i file temporanei e viola abbiamo un nuovo file che inizia con la parola "virgolette" che possiamo usare per i nostri altri processi.

La mia domanda è:
perché devo fare una dichiarazione sed per rimuovere il tag FEFF in quel file temporaneo? Il file originale non ce l'ha, ma appare sempre nella sostituzione. All'inizio ho pensato che cp stava causando questo, ma se inserisco la dichiarazione sed da rimuovere prima del cp, non c'è.

Forse sto solo perdendo qualcosa ...

+0

Si prega di inviare l'origine per 'clean.sed'. Quale dei file .tmpX appare per la prima volta? – wallyk

+2

0xfeff è un contrassegno di ordine byte unicode. Non sei sicuro di cosa lo aggiunga nel tuo caso. – Eugene

+2

Prima domanda: perché si creano 4 file temporanei per farlo invece di usare in-place (sed -i) su $ 1,1st ogni volta? Secondo: quando inizia a comparire il marker dell'ordine dei byte (feff)? È lì subito dopo aver eseguito clean.sed? Se è così, potresti voler postare quello script. Terzo [nitpick]: non è necessario sfuggire alle virgolette quando ci si trova tra virgolette singole e non è mai necessario sfuggire alle virgole. 's /,/","/g' è molto più leggibile di 's/\,/\ "\, \"/g'. – glomad

risposta

15

U + FEFF è il punto di codice per un byte order mark. I tuoi file molto probabilmente contengono dati salvati in UTF-16 e il BOM è stato corrotto dal tuo 'processo di pulizia' che molto probabilmente si aspetta in ASCII. Probabilmente non è una buona idea rimuovere il BOM, ma invece correggere gli script per non corromperlo in primo luogo.

+0

questo è quello che ho pensato troppo, ma lui afferma chiaramente nella domanda che la distinta non è nel file originale. – glomad

+0

Una distinta base è invisibile La mia ipotesi migliore data l'informazione nella domanda è che lo script clean.sed cambia i caratteri non stampabili nella loro rappresentazione esadecimale e, eventualmente, rimuove anche i caratteri NUL. Quindi la distinta base potrebbe essere stata sempre presente, diventa solo più visibile dopo la "pulizia" –

+0

qui è clean.sed: s/\ ", \"/XXX/g; : un s /, // g ta s/XXX/\ "\"/g; – SDGuero

2

per sbarazzarsi di questi in emacs GNU:

  1. Aprire Emacs
  2. fare una ricerca-file-letteralmente per aprire il file
  3. Modifica al largo delle principali tre byte
  4. salvare il file

C'è anche un modo per convertire i file con convenzione di terminazione di linea DOS in convenzione di terminazione di linea Unix.

+0

In Emacs 'C-x RET f' e specificare' utf-8' –

Problemi correlati