2009-12-29 15 views
11

J'ai écrit un script qui nettoie les fichiers .csv, en supprimant quelques mauvaises virgules et des citations mauvais (mauvais, signifie qu'ils rompent un programme dans la maison que nous utilisons pour transformer ces fichiers) en utilisant sed:Pourquoi mon script Bash ajoute-t-il <feff> au début des fichiers?

# 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 

ici est clean.sed:

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

Ensuite, il supprime les fichiers temporaires et alto, nous avons un nouveau fichier qui commence par le mot « citations » que nous pouvons utiliser pour nos autres processus.

Ma question est:
Pourquoi dois-je faire une déclaration sed pour supprimer la balise feff dans ce fichier temporaire? Le fichier original ne l'a pas, mais il apparaît toujours dans le remplacement. Au début, je pensais que cp causait cela, mais si je mets dans la déclaration sed à enlever avant le cp, il n'est pas là.

Peut-être que je manque juste quelque chose ...

+0

Veuillez indiquer la source de 'clean.sed'. Lequel des fichiers .tmpX apparaît-il en premier? – wallyk

+2

0xfeff est une marque d'ordre octet unicode. Je ne sais pas exactement ce qui l'ajoute dans votre cas. – Eugene

+2

Première question: Pourquoi créez-vous 4 fichiers temporaires pour ce faire au lieu d'utiliser in-situ (sed -i) sur 1,1 $ à chaque fois? Deuxième: Quand le marqueur d'ordre des octets (feff) commence-t-il à apparaître dans votre processus? Est-il présent immédiatement après l'exécution de clean.sed? Si c'est le cas, vous pouvez publier ce script. Troisième [nitpick]: vous n'avez pas besoin d'échapper les guillemets lorsque vous êtes entre guillemets simples, et vous n'avez jamais besoin d'échapper les virgules. 's /,/","/g' est beaucoup plus lisible que 's/\,/\ "\, \"/g'. – glomad

Répondre

15

U + FEFF est le point de code pour un byte order mark. Vos fichiers contiennent très probablement des données sauvegardées en UTF-16 et la nomenclature a été corrompue par votre "processus de nettoyage" qui attend le plus probablement ASCII. Ce n'est probablement pas une bonne idée de supprimer la nomenclature, mais plutôt de corriger vos scripts pour ne pas la corrompre en premier lieu.

+0

C'est ce que je pensais aussi, mais il indique clairement dans la question que la nomenclature n'est pas dans le fichier d'origine – glomad

+0

Une BOM est invisible.Ma meilleure estimation, étant donné que le script clean.sed change les caractères non imprimables en leur représentation hexadécimale, et supprime éventuellement les caractères NUL.La BOM était peut-être là depuis le début, elle devient plus visible après le "nettoyage" –

+0

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

2

Pour se débarrasser de ces derniers dans GNU emacs:

  1. Ouvrir Emacs
  2. Faites une découverte-file-literally pour ouvrir le fichier
  3. Modifier off les trois principaux octets
  4. Enregistrez le fichier

Il existe également un moyen de convertir des fichiers avec la convention de terminaison de ligne DOS en convention de terminaison de ligne Unix.

+0

Dans Emacs 'C-x RET f' et spécifiez' utf-8' –