La Fibre

Télécom => Logiciels et systèmes d'exploitation => Linux Linux => Discussion démarrée par: vivien le 20 décembre 2013 à 10:35:47

Titre: Découper un CSV en plusieurs petits fichiers automatiquement
Posté par: vivien le 20 décembre 2013 à 10:35:47
Petit script perl pour couper un fichier .CSV de plus de 1 million de lignes (limite de Excel et Calc) en plusieurs fichiers de 900 000 lignes pour pouvoir l'ouvrir dans un tableur  :

Ce script va découper un ficher all.csv en plusieurs fichiers fichier001.csv, fichier002.csv, fichier003.csv,... d'une taille maximum de 900 000 lignes.

Tout se paramètre facilement :

#!/usr/bin/perl
use strict;
use warnings;
use autodie;

# Variable à modifier :
my $Chemin = "/home/vivien/";
my $FichierSource = "all.csv";
my $NbLigneMax = "900000";
my $FichierSortie = "fichier";
my $FichierSortieExtension = ".csv";

my $FichierNumero = 1;
open(my $fout, ">", $Chemin.$FichierSortie.sprintf("%03d", $FichierNumero++).$FichierSortieExtension);
open(my $fin, "<", $Chemin.$FichierSource);
while (<$fin> ) {
 print $fout $_;
 if ($. % $NbLigneMax == 0) {
   close($fout);
   open($fout, ">", $Chemin.$FichierSortie.sprintf("%03d", $FichierNumero++).$FichierSortieExtension);
 }
}
close($fout);
close($fin);

Merci à gilou de http://forum.hardware.fr (http://forum.hardware.fr)
Titre: Découper un CSV en plusieurs petits fichiers automatiquement
Posté par: Amon-Ra le 20 décembre 2013 à 11:08:31
oula ce script pique les yeux...
y'a plus simple et plus performant !

tu utilises la commande unix "split"

split -l 900000 "all.csv" "fichier."

fichier.aa
fichier.ab
fichier.ac
...

apres suffit de d’exécuter une commande de renommage du fichier pour les avoirs sur la forme que tu veux :

for i in fichier.*;do mv $i $i.csv ;done

#!/usr/bin/sh
split -l 900000 $1 $2
for i in fichier.*;do mv $i $i.csv ;done

=> chmod 755 monscript.sh
=> ./monscript.sh all.csv "fichier."

tips : l'option -d permet d'utiliser un index numérique, bref le man t'en dira plus
Titre: Découper un CSV en plusieurs petits fichiers automatiquement
Posté par: vivien le 20 décembre 2013 à 13:45:00
Merci,

C'est plus propre effectivement.

Si vous avez beosin de trier un fichier CSV en ligne de commande (par exemple avant de le découper en bout de 900 000 lignes), voici la commande sous linux pour trier le ficheir via la colonne N°11 :

cat original.csv | sort -t";" -k11n,11n > all.csv

Titre: Découper un CSV en plusieurs petits fichiers automatiquement
Posté par: vivien le 14 février 2014 à 18:42:38
Encore un script autour des CSV qui pique les yeux, je l'ai crée il y a 7 ans... en bash !
Le but (en lisant le code, je ne me souviens plus pourquoi je l'ai crée) est de transformer un fichier .txt en fichier .csv

#!/bin/dash
####################################################################################
# SYNOPSIS : bincsv nom_du_fichier_de_log_sans_l'extension_.txt                    #
#                                                                                  #
# DESCRIPTION :                                                                    #
#   Transforme un fichier log de l'appli xxx en fichier .csv                       #
#                                                                                  #
# DEPENDANCES :                                                                    #
#   /bin/bash                                                                      #
#   /bin/cat                                                                       #
#   /bin/date                                                                      #
#   /usr/bin/cut                                                                   #
#                                                                                  #
####################################################################################

############################################################################################
#### Tests des arguments passé au script ####
############################################################################################
if [ "$1" == "" ] ; then
  echo "Manque arguments"
  echo "SYNOPSIS : ${0} nom_du_fichier_de_log_sans_l'extension_.txt"
  exit 1
fi

FICHIER_SOURCE="$1.txt"
FICHIER_DEST="$1.csv"

if [ ! -e "$FICHIER_SOURCE" ] ; then
  echo "ERREUR :"
  echo "Le fichier de log $FICHIER_SOURCE n'existe pas"
  echo "SYNOPSIS : ${0} nom_du_fichier_de_log_sans_l'extension_.txt"
  exit 1
fi

if [ -e "$FICHIER_DEST" ] ; then
  echo "ERREUR :"
  echo "Le fichier $FICHIER_DEST existe déja"
  echo "Ce script s'arrete pour ne pas l'effacer"
  exit 1
fi

echo -e -n "" > ${FICHIER_DEST}

if [ ! -e "$FICHIER_DEST" ] ; then
  echo "ERREUR :"
  echo "Impossible de créer le fichier $FICHIER_DEST"
  echo "Vérifiez les droit en écriture dans le répertoire"
  exit 1
fi

############################################################################################
#### Initialisation ####
############################################################################################
DATE_DEBUT_SCRIPT=$(/bin/date)
RET_LIGNE=$(echo -e -n "\r") # caractère de retour chariot

echo "Bonjour ! Opération en cours : ${FICHIER_SOURCE} => ${FICHIER_DEST}"

############################################################################################
#### Boucle principale exécutée pour ligne du fichier source ####
############################################################################################
# Lecture mot à mot du fichier
for BRUT_LIGNE in $(/bin/cat ${FICHIER_SOURCE}); do

 # Si EVENT détecté on passe a la ligne dans le fichier .csv
 if [ "$BRUT_LIGNE" == "EVENT$RET_LIGNE" ]; then
  echo -e "\n"
  echo -e -n "\n" >> ${FICHIER_DEST}
 fi

 DER_CAR=$(echo "$BRUT_LIGNE" | /usr/bin/cut -c ${#BRUT_LIGNE}) # dernier car de la ligne

 if [ "${DER_CAR}" == "${RET_LIGNE}" ]; then

  if [ "${BRUT_LIGNE}" == "${RET_LIGNE}" ]; then

   # retour chariot détecté => on n'écrit rien dans le .csv
   echo -n "R"

  else

   # dernier caractère est retour chariot : on remplace le retour chariot par un ;
   echo -n "L"
   BRUT_LIGNE=$(echo "$BRUT_LIGNE" | /usr/bin/cut -c 1-$((${#BRUT_LIGNE}-1)))
   echo -n "${BRUT_LIGNE}" >> ${FICHIER_DEST}
   echo -n ";" >> ${FICHIER_DEST}
  fi

 else

  # dernier caractère n'est pas un retour chariot => on est sur la même ligne, on n'oublie pas de rajouter l'espace supprimé
  echo -e -n "."
  echo -n "${BRUT_LIGNE} " >> ${FICHIER_DEST}

 fi

done # fin du traitement pour ce mot, on passe au suivant
############################################################################################
#### Fin Boucle principale executée pour chaque ligne du fichier source ####
############################################################################################

DATE_FIN_SCRIPT=$(/bin/date)
LOAD_AVERAGE=$(/bin/cat /proc/loadavg | /usr/bin/cut -c 1-14)
echo ""
echo ""
echo "Opération réalisée : ${FICHIER_SOURCE} => ${FICHIER_DEST}"
echo "Date Debut Script  : ${DATE_DEBUT_SCRIPT}"
echo "Date Fin Script    : ${DATE_FIN_SCRIPT}"
echo "Load Average       : ${LOAD_AVERAGE}"
Titre: Découper un CSV en plusieurs petits fichiers automatiquement
Posté par: reno31 le 15 février 2014 à 09:57:28
sed 's/;/<tab>/g' > file.csv

le <tab> étant le charactère de délimitation dans le fichier texte. (\t pour un tab)