La plupart des fichiers CSV « corrompus » ne le sont pas. Un CSV est un fichier texte, et un fichier texte se dégrade rarement. Presque toujours, le fichier a été écrit avec une série d'hypothèses et il est lu avec une autre : un autre séparateur, un autre encodage, une règle de guillemets que l'export a mal appliquée.
Il faut donc diagnostiquer avant de réparer. Le symptôme vous dit laquelle des six causes est en jeu, et chacune a sa solution.
La réponse rapide
Regardez d'abord les octets bruts, pas le fichier ouvert dans un tableur, qui est justement un outil qui cache les indices :
head -5 broken.csv # the actual separators and quotes
file -I broken.csv # the real encoding
wc -l broken.csv # how many lines it thinks there are
Associez ensuite le symptôme à sa cause :
| Symptôme | Cause | Solution |
|---|---|---|
| Tout dans une seule colonne | Mauvais séparateur | Rouvrir en l'indiquant |
é, ’, ü | UTF-8 lu comme du Latin-1 | Rouvrir en UTF-8 |
 collé au premier en-tête | Marque d'ordre des octets | Supprimer le BOM |
| Lignes coupées au milieu d'un enregistrement | Saut de ligne dans un champ | Corriger les guillemets |
| Le nombre de colonnes dérive après la ligne N | Un guillemet non échappé | Trouver et réparer la ligne N |
| Le fichier s'arrête en pleine ligne | Écriture tronquée | Réexporter |
1. Tout atterrit dans une seule colonne
De loin le cas le plus courant, et ce n'est jamais la faute du fichier.
Une grande partie de l'Europe continentale utilise le point-virgule, parce que la virgule y sert de séparateur décimal. Beaucoup d'exports étiquetés .csv sont en réalité séparés par des tabulations. head -5 vous montre lequel en une seconde.
La solution consiste à dire au lecteur quel est le séparateur, pas à faire un rechercher-remplacer. Remplacer les points-virgules par des virgules touche aussi ceux qui se trouvent dans des valeurs entre guillemets, et vous avez alors un fichier réellement cassé.
- Excel : ne double-cliquez pas. Données → À partir du texte/CSV, puis choisissez le séparateur dans l'aperçu.
- Google Sheets : Fichier → Importer → séparateur Personnalisé.
- Ligne de commande :
duckdb -c "SELECT * FROM read_csv('broken.csv', delim=';')" - Sur téléphone : une application qui permet de rouvrir un fichier avec des réglages d'analyse explicites, plutôt qu'une qui devine une fois et abandonne.
Détecte automatiquement séparateurs, en-têtes et encodages et, c'est le point qui compte ici, permet de rouvrir un fichier avec des réglages d'analyse personnalisés quand la détection se trompe.
Ce que ça fait2. Mojibake : é au lieu de é
L'erreur d'encodage classique. Le fichier est en UTF-8 et quelque chose l'a lu comme du Latin-1 ou du Windows-1252. Les octets sont intacts ; c'est l'interprétation qui ne l'est pas.
file -I broken.csv
# broken.csv: text/plain; charset=utf-8
La solution : rouvrir en déclarant l'UTF-8. Dans Excel, la boîte de dialogue d'import propose une liste Origine du fichier. Choisissez 65001 : Unicode (UTF-8). En ligne de commande :
iconv -f WINDOWS-1252 -t UTF-8 broken.csv > fixed.csv
Faites attention au sens. Si le fichier est vraiment en Windows-1252 (anciens systèmes, certains exports d'ERP), cette commande le convertit. Si le fichier est déjà en UTF-8 et simplement affiché de travers, la conversion aggrave les choses : vous encoderiez le mojibake. Vérifiez avec file -I avant de lancer quoi que ce soit.
3. order_id dans le nom de la première colonne
Une marque d'ordre des octets UTF-8 : trois octets invisibles au début du fichier, écrits par Excel et par beaucoup d'outils Windows. Elle fausse la correspondance des en-têtes dans les scripts et apparaît comme du bruit dans les analyseurs naïfs.
sed -i '' '1s/^\xEF\xBB\xBF//' broken.csv # macOS
sed -i '1s/^\xEF\xBB\xBF//' broken.csv # Linux
Ne la supprimez que si un outil en aval s'étrangle dessus. Excel, lui, veut le BOM. C'est ce qui lui permet de reconnaître un CSV en UTF-8 au double-clic, et c'est en le retirant que vous faites apparaître des accents cassés chez le collègue à qui vous envoyez le fichier.
4. Des lignes coupées en deux
Vous attendiez 10 000 lignes et vous en avez 10 340, avec des fragments là où devraient se trouver des adresses. Un champ contient un vrai saut de ligne : une adresse, une zone de commentaire, un paragraphe collé.
C'est du CSV valide si le champ est entre guillemets :
id,name,notes
1,"Alice","Called back.
Wants a refund."
La RFC 4180 l'autorise, et tout analyseur correct sait le gérer. Le problème survient quand un outil découpe aux sauts de ligne avant de s'occuper des guillemets, ce qui décrit la plupart des commandes shell en une ligne, plusieurs importateurs de tableur et beaucoup de code écrit à la main.
La solution passe généralement par le lecteur, pas par le fichier. Utilisez un analyseur qui comprend les guillemets : DuckDB, le module csv de Python, csvkit, ou n'importe quel vrai import de tableur. Si le champ n'est vraiment pas entre guillemets, l'export est défectueux, et réexporter est plus rapide que réparer.
Pour savoir dans quel cas vous êtes :
csvclean -n broken.csv # reports rows with the wrong field count
5. Tout ce qui suit la ligne 4 812 est faux
Le nombre de colonnes dérive en cours de route et ne se rétablit jamais. C'est un seul guillemet non échappé, et tout ce qui suit est lu à l'intérieur d'une chaîne qui ne se ferme jamais.
id,product,price
1,"6"" pipe",4.50
Ce 6" aurait dû être écrit 6"". À la place, l'analyseur voit la valeur se terminer à 6, puis un " isolé en ouvre une nouvelle, et le reste du fichier se retrouve dedans.
Pour la trouver :
csvclean -n broken.csv
awk -F',' 'NF != 3 {print NR": "$0}' broken.csv # rough, ignores quoting
csvclean est la méthode fiable ; la ligne awk est une approximation rapide pour les fichiers sans virgules entre guillemets. Une fois le numéro de ligne en main, corrigez cette ligne à la main : soit en doublant le guillemet intérieur, soit en le remplaçant par in. et en passant à autre chose.
Sur téléphone, c'est pénible sans une application capable d'aller à une ligne et de modifier une seule cellule :
Ouvre le fichier en entier et permet d'y faire des recherches, pour trouver la ligne où la structure déraille avant de décider de réparer ou de réexporter.
Ce que ça fait6. Le fichier s'arrête net
La dernière ligne est un enregistrement à moitié écrit, ou la taille du fichier est étrangement ronde. L'écriture a été interrompue, ou le téléchargement.
tail -3 broken.csv
Il n'y a rien à réparer ici. Les données n'ont jamais été écrites. Supprimez la dernière ligne incomplète et acceptez la perte, ou réexportez. S'il s'agissait d'un téléchargement, comparez Content-Length à la taille réelle avant d'accuser le fichier.
Les règles de réparation
Quatre habitudes qui rendent la plupart de ces problèmes anodins :
- Travaillez sur une copie.
cp broken.csv broken.backup.csv. Chaque correctif de cette page est une hypothèse tant qu'il n'est pas vérifié, et une hypothèse qu'on ne peut pas annuler est un mauvais marché. - Corrigez le lecteur avant le fichier. La plupart des symptômes ici viennent d'un mauvais réglage. Réécrire les données pour satisfaire un analyseur mal configuré vous laisse avec deux problèmes.
- Ne faites jamais de rechercher-remplacer sur les séparateurs. Il touche ceux qui sont dans les valeurs entre guillemets et transforme un fichier lisible en fichier corrompu.
- Comptez les lignes avant et après. À chaque réparation. Si le nombre a changé sans que vous l'ayez voulu, la réparation a cassé quelque chose.
Quand abandonner et réexporter
Si plus d'une poignée de lignes sont structurellement fausses, arrêtez de réparer. Un export défectueux signifie généralement que l'outil d'export a un bogue de guillemets, et chaque ligne qu'il produit est suspecte, y compris celles qui paraissent correctes aujourd'hui. Redemandez le fichier, et demandez-le avec des guillemets.