• Contatto
  • Note Legali
  • Privacy
  • FAQs
  • Downloads
  • Collabora
  • Supporta
  • Splitcsv: dividi automaticamente i tuoi files csv su Linux

    Scritto da Erriko in Bash Scripting, Linux il 9 febbraio 2010

    Capita di trovarsi obbligati a lavorare su enormi files CSV (comma separated values): cataloghi, dump di interi database in .csv (magari esportati da PhpMyAdmin oppure con lo script php che vi ho proposto tempo fa)…

    E’ ovvio che quando un file del genere contiene centinaia di migliaia, se non milioni di righe è molto difficile riuscire a gestirlo con un comune editor o con OpenOffice. 
    Per questo motivo è utile spezzettare il file in più parti, ciascuna costituita da un numero ragionevole di righe , così da rendere il tutto più manegevole.

    Nel caso di CSV destinati all’importazione con PhpMyAdmin, per altro, non saremmo in grado di importare un file ad esempio di 300 mb in quanto sarebbe certamente una dimensione di gran lunga superiore a quella massima consentita (in genere sugli hosting condivisi è concesso un massimo di soli 2mb per file).

    Grazie alla potente riga di comando di Linux (o comunque in generale dei sistemi Unix-like), grazie al comando split è possibile dividere un qualsiasi file di testo (il .csv infatti non è altro che un particolare tipo di file di testo) automaticamente e senza il bisgono di aprire il file.

    Tuttavia utilizzando split i files generati non rispetteranno il formato CSV in quanto non avranno (a parte il primo) i nomi dei campi riportati sulla prima riga. Cosa che crea non pochi problemi quando il file .csv in questione è destinato ed essere importato su phpmyadmin piùttosto che su altre piattaforme.

    Per questo motivo, spinto dall’esigenza di dover importare cataloghi enormi su varie piattaforme di ecommerce, o (come mi è successo proprio ieri) di dover importare una tabella da un milione di righe con PhpMyAdmin, ho deciso di scrivere uno script bash (uno di quei famosi .sh che usiamo spessissimo su Linux) che renderà del tutto automatiche le procedure di divisione del file e di inserimento dell’header (la riga riportante i nomi dei campi).

    Visto che questo script mi è stato utilissimo e visto che cercando per la rete ho trovato poco e niente (altrimenti non mi sarei fatto lo script da solo :-P ), credo che questo file possa essere di giovamento a tanti altri utenti (e non) di Erriko.it. Ovviamente, data la mia “immensa fantasia”, ho chiamato questo script SPLITCSV.

    Ecco il codice dello script (mi scuso per l’orribile inglese dei commenti, ma li ho inseriti alle 5 del mattino :-D ) :


    #!/bin/bash         
    
    # this script is brought to you by Enrico Deleo. You can republish it as many times as you like, but PLEASE
    # cite the source WWW.ERRIKO.IT, it will be much appreciated.    
    
    # the script starts here
    
    # check if the user has specified a file to split
    
    if [ ! $# == 2 ]; then
      echo ""
      echo "Please specify all required arguments."
      echo "Usage: you must specify the filename and the number of lines you want to put into each file."
      echo ""
      echo "e.g.:  ./splitcsv.sh filename.csv linesperfile"
      echo ""
      exit
    fi
    
    # extract the name of the files without the extension (.csv, .txt or whatever)
    
    NAME=`echo "$1" | cut -d'.' -f1`
    
    # count total lines and save the output into a variable
    
    NLINES=`wc -l $1`
    
    # the command wc returns the total amount of the lines and the file name, but here we need ONLY the number.
    # with the following line we'll put into a new variable only what we need
    
    NUMBER=`echo $NLINES | { read first rest ; echo "$first"; }`
    
    # we must not consider the first row, as it is our header...
    
    TOTAL=`expr $NUMBER - 1`
    
    # create a directory to store the output:
    
    mkdir Split
    
    # save the first row (the header) of our csv into a temporary file
    
    head -n 1 $1 > header.csv
    
    # create a temporary file containing the content without
    # the header:
    
    tail -$TOTAL $1 > content.csv
    
    # split the content file into multiple files of n lines and name each one with a name based on the original filename:
    
    split -l $2 content.csv Split/"$NAME"_
    
    # loop through the new split files, adding the header
    # and a '.csv' extension:
    for f in Split/*; do cat header.csv $f > $f.csv; rm $f; done;
    
    # remove the temporary files:
    rm header.csv
    rm content.csv
    
    echo ""
    echo "Congratulations, your file has been successfully split!"
    echo "Thank you for using splitcsv by Erriko - www.erriko.it"
    echo ""


    Utilizzare questo script è semplicissimo: basta copiare ed incollare il codice riportato sopra all’interno di un file di testo e rinominarlo con il nome splitcsv.sh

    Una volta creato il file basta aprire un terminale e recarsi nella cartella dove questo è contanuto e renderlo eseguibile digitando:

    chmod +x splitcsv.sh

    A questo punto per dividere il file è sufficiente digitare

    ./splitcsv.sh nomefile.csv numerorighe

    dove chiaramente nomefile.csv sta per il nome del file che vogliamo suddividere (completo di percorso nel caso non si trovi nella stessa cartella dello script) e e numerorighe sta per il numero di righe (espresso in cifre) che ogni file può contenere (10,100,1000,39848 ecc…)

    Spero troviata utile questo script, e attendo con ansia vostri feedback! Lo script è stato testato su Ubuntu 9.10, ma dovrebbe funzionare su tuttle distribuzioni e, chi lo sa, probabilmente anche su MacOSX (ma attendo conferme da parte vostra)

    Articoli Correlati

    Rendi la scrivania di Linux identica a Windows XP
    PHP: reindirizzare automaticamente l’utente alla pagina della propria lingua
    Creare facilmente files pdf senza comprare Adobe Acrobat
    Esportare una tabella da un database MySql in CSV utilizzando PHP

    Non ci sono ancora commenti... Perchè non essere il primo?!?

    Commenta