Manipulation de gros fichier CSV
Bonjour.
Je souhaite traiter un fichier qui est au format CSV et très volumineux (20 millions d'enregistrements, 48 champs, 4 Go).
Il faudrait :
- Supprimer des "colonnes".
- Remplacer des chaines de caractères.
- Enlever les quotes si besoin et remplacer les "," par des ";"
- Dans l'idéal, formater un champ numérique (afficher le nombre sur 9 caractères avec des zéros devant : '27' => '000000027')
J'ai essayé avec Python, le traitement me prend moins de 5 minutes 8-)
Mais c'est pour le travail, et au travail je n'ai (normalement) pas accès à Python :(
En fait, je n'ai accès qu'à Powershell (et JS, mais j'ai des légers doutes pour un traitement de ce genre:mrgreen:)
J'ai trouvé un exemple sur le blog de Balladelli. Après adaptation j'ai donc cette commande qui conserve uniquement les champs souhaités :
Code:
Import-Csv MonGrosFichier.csv | Select champ1, champ2, champ5, champ6, champ24, champ42| Export-Csv MonPetitFichier.csv –NTI -Delimiter ';'
Il me reste ensuite à traiter les chaines de caractères, avec des .replace() (plus rapides que _replace, si j'ai bien suivi) sur un fichier plus petit (2 Go) :
Code:
(Get-Content $csvfile) | Foreach-Object {$_.replace('"', '').replace('true', '1').replace('false',0)}|Out-File $csvfile
Problèmes :
- la première étape me prend énormément de temps : 2 heures (calculé avec Measure-Command {})
- la deuxième étape est tellement gourmande ( 6 Go de RAM pour traiter un fichier qui en fait 2) que j'ai fini par tuer le processus 8O
A titre indicatif, mon script Python me prend 5 minutes pour tout faire :weird:
Il y a moyen d'optimiser le traitement (éventuellement en passant par Get-Content pour la première étape, ou en faisant une lecture ligne à ligne) ? Ou de forcer l'utilisation de plusieurs threads/plus de mémoire ?
Ou je dois considérer que PS ne pourra pas mieux faire ?
PS :
Quand je parle de Python, ce n'est pas pour dire que PS est mauvais c'est juste pour avoir un point de comparaison : l'ordinateur est capable de faire le traitement demandé en 5 minutes. S'il n'y arrive pas, c'est soit que PS n'est pas adapté pour ce genre de traitement, soit que les commandes ne sont pas bonnes...
Comment enlever l’entête du fichier csv sans faire get-content
Bonjour,
Je suis en face d'une problématique d'optimisation lors de la copie d'un fichier d'un dossier vers un autre.
je m'explique :
je reçois un fichier csv avec l'entête, et je souhaite enlever cet entête sauf que quand je reçois de gros fichiers (de l'ordre de 1 million de lignes), le traitement prend un temps fou!!!
ci-dessous le script que j'ai fait et qui marche très bien pour des fichiers non volumineux
Code:
1 2 3 4
| $MyFile = Get-Content $pathTmp\$file
$MyFile[1..($MyFile.length-1)] > $pathTmp\$file
$MyFile1 = Get-Content $pathTmp\$file
$MyFile1 | Out-File -Encoding "Default" $pathTmp\$Newname |
ce script ouvre le fichier(get-content) avec entête $file, puis enlève l'entête, le stocke dans $MyFile1 et le relit encore une fois et l'enregistrer pour le déplacer!!!
cette manip de lecture pour enlever l'entête consomme beaucoup de temps.
Ma demande est comment réécrire ce script de façon à enlever l'entête sans faire des get-content ?
Merci pour votre aide