[Shell]Découper proprement gros fichier Inbox

wolfen -  
wolfen13fr Messages postés 1 Statut Membre -
Bonjour,

Régulièrement, nous avons des utilisateurs qui laissent "gonfler" leur fichier Inbox sous Thunderbird et celui-ci arrive alors à la limite de 4Go !

La solution que j'ai trouvé jusqu'à maintenant, c'est de manuellement découper le fichier en plusieurs fichiers d'1 000 000 de ligne (environ 740 Mo par fichier) puis de rassembler la fin du premier fichier avec le début du second pour reconstituer le dernier mail du fichier découpé, la fin du deuxième avec le début du troisième, etc ...

Je pense qu'il est faisable de scripter tout ceci en shell.
Je sais déjà comment découper mon fichier en plusieurs morceaux :

split -1000000 Inbox archive


Avec ça, j'obtiens 6 fichiers nommé "archiveaa", archiveab" ... "archiveaf".

Cette partie là, c'est simple ... Par contre, pour l'ajustement, je ne sais pas trop comment faire.

Je sais qu'un message dans un fichier Inbox commence par le schéma "From - ". Mais comment dire au script de prendre la dernière occurrence de ce schéma, de couper ce qui suit et de le coller au début du fichier suivant pour reconstituer le message ? Là, je bloque.

Utiliser sed ou awk ? Est-ce que quelqu'un a un début de piste pour la deuxième partie ?

Merci d'avance !

2 réponses

  1. wolfen
     
    Je m'auto-réponds, après deux jours de recherche et de bidouillage ...

    Voici un script un peu tarabiscotté mais qui fonctionne sous Linux (Ubuntu 10.04 LTS) :

    #!/bin/sh
    
    # script shell "decoupagembox.sh" version Linux - Ubuntu 10.04 LTS
    #
    # Ce script découpe un fichier au format mbox en plusieurs archive.
    # Le nombre de mails par archive est paramétrable. La taille de chaque archive
    # dépendra du poids des mails et donc des pièces jointes liés.
    
    # février 2011
    # code sous licence Creative Commons by-nc-sa (diffusion libre et modifiable
    # en citant l'auteur d'origine et sans utilisation commerciale
    #
    # auteur : Damien MAURAN,
    # dmauran@gmail.com
    
    
    echo "Découpage d'un fichier format mbox en plusieurs archives ..."
    echo
    
    if test "$1" = ""
    then echo "Veuillez indiquer le nom du fichier à traiter, le nombre de mail par archive"
    echo "et le chemin de destination. Exemple :"
    echo
    echo "decoupagembox.sh nom_fichier_source xx chemin_de_destination/"
    echo
    echo "où xx est le nombre de mail par archive. Si xx n'est pas indiqué,"
    echo "la valeur par défaut sera de 500 mails par archive."
    echo
    echo "Fin du script ... aucun traitement réalisé."
    exit 0
    fi
    
    if test "$3" = ""
    then echo "Veuillez indiquer le nom du fichier à traiter, le nombre de mail par archive"
    echo "et le chemin de destination. Exemple :"
    echo
    echo "decoupage.sh nom_fichier xx chemin_de_destination/"
    echo
    echo "où xx est le nombre de mail par archive. Si xx n'est pas indiqué,"
    echo "la valeur par défaut sera de 500 mails par archive."
    echo
    echo "Fin du script ... aucun traitement réalisé."
    exit 0
    fi
    
    if test "$2" = ""
    then X=$((500))
    else
    X=$(($2))
    fi
    
    date_debut=$(date)
    
    echo "** Début de traitement : $date_debut **"
    echo
    echo "isolation des emails : 1 email = 1 fichier"
    echo 
    echo "Veuillez patienter, cela peut prendre du temps ..."
    echo
    
    awk '/From - /{n++}{print >"/tmp/mboxout" n ".txt" }' $1
    
    ls /tmp/mboxout*.txt | wc -l > compteur.txt
    nb='cat compteur.txt'
    
    rm compteur.txt
    
    nombre=$(($nb))
    echo "Nombre de mails extraits : $nombre"
    
    compteur1=$(($nb/$X))
    echo "Nombre de paquet de $X mails : $compteur1 paquets + 1 paquet des mails restants"
    echo
    echo "Regroupement des mails pour créer les archives"
    echo
    echo "Veuillez patienter ..."
    echo
    
    compteur2=$((compteur1+1))
    
    for i in $(seq 0 1 $compteur2)
    do
    	nb_fic=$(($i*$X));
    	fin_fic=$(($nb_fic+$X));
    	for j in $(seq $nb_fic 1 $fin_fic)
    		do
    		if test -f "/tmp/mboxout$j.txt"
    		then cat /tmp/mboxout$j.txt >> archive$i;
    		fi
    	done;
    done
    
    rm /tmp/mboxout*.txt
    
    
    echo "Les fichiers archives suivants ont été créés :"
    ls -x archive*
    echo
    mv archive* $3
    echo "Ils ont été sauvés dans : $3/"
    echo
    
    date_fin=$(date)
    echo "** fin de traitement : $date_fin **"
    exit 0
    


    Et au cas où, voici le même code mais optimisé pour Mac OS X (version 10.6.5) :
    #!/bin/sh
    
    # script shell "decoupagembox.sh" version Mac OS X (version 10.6.5)
    #
    # Ce script découpe un fichier au format mbox en plusieurs archive.
    # Le nombre de mails par archive est paramétrable. La taille de chaque archive
    # dépendra du poids des mails et donc des pièces jointes liés.
    
    # février 2011
    # code sous licence Creative Commons by-nc-sa (diffusion libre et modifiable
    # en citant l'auteur d'origine et sans utilisation commerciale
    #
    # auteur : Damien MAURAN,
    # dmauran@gmail.com
    
    
    echo "Découpage d'un fichier format mbox en plusieurs archives ..."
    echo
    
    if test "$1" = ""
    then echo "Veuillez indiquer le nom du fichier à traiter, le nombre de mail par archive"
    echo "et le chemin de destination. Exemple :"
    echo
    echo "decoupage.sh nom_fichier xx chemin_de_destination/"
    echo
    echo "où xx est le nombre de mail par archive. Si xx n'est pas indiqué,"
    echo "la valeur par défaut sera de 500 mails par archive."
    echo
    echo "Fin du script ... aucun traitement réalisé."
    exit 0
    fi
    
    if test "$3" = ""
    then echo "Veuillez indiquer le nom du fichier à traiter, le nombre de mail par archive"
    echo "et le chemin de destination. Exemple :"
    echo
    echo "decoupage.sh nom_fichier xx chemin_de_destination/"
    echo
    echo "où xx est le nombre de mail par archive. Si xx n'est pas indiqué,"
    echo "la valeur par défaut sera de 500 mails par archive."
    echo
    echo "Fin du script ... aucun traitement réalisé."
    exit 0
    fi
    
    if test "$2" = ""
    then X=$((500))
    else
    X=$(($2))
    fi
    
    date_debut=$(date)
    
    echo "** Début de traitement : $date_debut **"
    echo
    echo "isolation des emails : 1 email = 1 fichier"
    echo 
    echo "Veuillez patienter, cela peut prendre du temps ..."
    echo
    
    awk '/From - /{n++}{filename = "/tmp/mboxout"n".txt"; print >> filename;close (filename) }' $1
    
    ls /tmp/mboxout*.txt | wc -l > compteur.txt
    nb='cat compteur.txt'
    
    rm compteur.txt
    
    nombre=$(($nb))
    echo "Nombre de mails extraits : $nombre"
    
    compteur1=$(($nb/$X))
    echo "Nombre de paquet de $X mails : $compteur1 paquets + 1 paquet des mails restants"
    echo
    echo "Regroupement des mails pour créer les archives"
    echo
    echo "Veuillez patienter ..."
    echo
    
    compteur2=$((compteur1+1))
    
    i=$((0))
    while [ $i -lt $compteur2 ]
    do
    	nb_fic=$(($i*$X));
    	fin_fic=$(($nb_fic+$X));
    	j=$(($nb_fic))
    	while [ $j -lt $fin_fic ]
    	do
    		if test -f "/tmp/mboxout$j.txt"
    		then cat /tmp/mboxout$j.txt >> archive$i;
    		fi
    		true $((j++))
    	done;
    	true $((i++))
    done
    
    rm /tmp/mboxout*.txt
    
    
    echo "Les fichiers archives suivants ont été créés :"
    ls -x archive*
    echo
    mv archive* $3
    echo "Ils ont été sauvés dans : $3/"
    echo
    
    date_fin=$(date)
    echo "** fin de traitement : $date_fin **"
    exit 0
    
    
    0
  2. wolfen13fr Messages postés 1 Statut Membre
     
    Je m'auto-réponds, après deux jours de recherche et de bidouillage ...

    Voici un script un peu tarabiscotté mais qui fonctionne sous Linux (Ubuntu 10.04 LTS) :

    #!/bin/sh

    # script shell "decoupagembox.sh" version Linux - Ubuntu 10.04 LTS
    #
    # Ce script découpe un fichier au format mbox en plusieurs archive.
    # Le nombre de mails par archive est paramétrable. La taille de chaque archive
    # dépendra du poids des mails et donc des pièces jointes liés.

    # février 2011
    # code sous licence Creative Commons by-nc-sa (diffusion libre et modifiable
    # en citant l'auteur d'origine et sans utilisation commerciale
    #
    # auteur : Damien MAURAN,

    echo "Découpage d'un fichier format mbox en plusieurs archives ..."
    echo

    if test "$1" = ""
    then echo "Veuillez indiquer le nom du fichier à traiter, le nombre de mail par archive"
    echo "et le chemin de destination. Exemple :"
    echo
    echo "decoupagembox.sh nom_fichier_source xx chemin_de_destination/"
    echo
    echo "où xx est le nombre de mail par archive. Si xx n'est pas indiqué,"
    echo "la valeur par défaut sera de 500 mails par archive."
    echo
    echo "Fin du script ... aucun traitement réalisé."
    exit 0
    fi

    if test "$3" = ""
    then echo "Veuillez indiquer le nom du fichier à traiter, le nombre de mail par archive"
    echo "et le chemin de destination. Exemple :"
    echo
    echo "decoupage.sh nom_fichier xx chemin_de_destination/"
    echo
    echo "où xx est le nombre de mail par archive. Si xx n'est pas indiqué,"
    echo "la valeur par défaut sera de 500 mails par archive."
    echo
    echo "Fin du script ... aucun traitement réalisé."
    exit 0
    fi

    if test "$2" = ""
    then X=$((500))
    else
    X=$(($2))
    fi

    date_debut=$(date)

    echo "** Début de traitement : $date_debut **"
    echo
    echo "isolation des emails : 1 email = 1 fichier"
    echo
    echo "Veuillez patienter, cela peut prendre du temps ..."
    echo

    awk '/From - /{n++}{print >"/tmp/mboxout" n ".txt" }' $1

    ls /tmp/mboxout*.txt | wc -l > compteur.txt
    nb='cat compteur.txt'

    rm compteur.txt

    nombre=$(($nb))
    echo "Nombre de mails extraits : $nombre"

    compteur1=$(($nb/$X))
    echo "Nombre de paquet de $X mails : $compteur1 paquets + 1 paquet des mails restants"
    echo
    echo "Regroupement des mails pour créer les archives"
    echo
    echo "Veuillez patienter ..."
    echo

    compteur2=$((compteur1+1))

    for i in $(seq 0 1 $compteur2)
    do
    nb_fic=$(($i*$X));
    fin_fic=$(($nb_fic+$X));
    for j in $(seq $nb_fic 1 $fin_fic)
    do
    if test -f "/tmp/mboxout$j.txt"
    then cat /tmp/mboxout$j.txt >> archive$i;
    fi
    done;
    done

    rm /tmp/mboxout*.txt

    echo "Les fichiers archives suivants ont été créés :"
    ls -x archive*
    echo
    mv archive* $3
    echo "Ils ont été sauvés dans : $3/"
    echo

    date_fin=$(date)
    echo "** fin de traitement : $date_fin **"
    exit 0

    Et au cas où, voici le même code mais optimisé pour Mac OS X (version 10.6.5) :
    #!/bin/sh

    # script shell "decoupagembox.sh" version Mac OS X (version 10.6.5)
    #
    # Ce script découpe un fichier au format mbox en plusieurs archive.
    # Le nombre de mails par archive est paramétrable. La taille de chaque archive
    # dépendra du poids des mails et donc des pièces jointes liés.

    # février 2011
    # code sous licence Creative Commons by-nc-sa (diffusion libre et modifiable
    # en citant l'auteur d'origine et sans utilisation commerciale
    #
    # auteur : Damien MAURAN,
    # dmauran@gmail.com

    echo "Découpage d'un fichier format mbox en plusieurs archives ..."
    echo

    if test "$1" = ""
    then echo "Veuillez indiquer le nom du fichier à traiter, le nombre de mail par archive"
    echo "et le chemin de destination. Exemple :"
    echo
    echo "decoupage.sh nom_fichier xx chemin_de_destination/"
    echo
    echo "où xx est le nombre de mail par archive. Si xx n'est pas indiqué,"
    echo "la valeur par défaut sera de 500 mails par archive."
    echo
    echo "Fin du script ... aucun traitement réalisé."
    exit 0
    fi

    if test "$3" = ""
    then echo "Veuillez indiquer le nom du fichier à traiter, le nombre de mail par archive"
    echo "et le chemin de destination. Exemple :"
    echo
    echo "decoupage.sh nom_fichier xx chemin_de_destination/"
    echo
    echo "où xx est le nombre de mail par archive. Si xx n'est pas indiqué,"
    echo "la valeur par défaut sera de 500 mails par archive."
    echo
    echo "Fin du script ... aucun traitement réalisé."
    exit 0
    fi

    if test "$2" = ""
    then X=$((500))
    else
    X=$(($2))
    fi

    date_debut=$(date)

    echo "** Début de traitement : $date_debut **"
    echo
    echo "isolation des emails : 1 email = 1 fichier"
    echo
    echo "Veuillez patienter, cela peut prendre du temps ..."
    echo

    awk '/From - /{n++}{filename = "/tmp/mboxout"n".txt"; print >> filename;close (filename) }' $1

    ls /tmp/mboxout*.txt | wc -l > compteur.txt
    nb='cat compteur.txt'

    rm compteur.txt

    nombre=$(($nb))
    echo "Nombre de mails extraits : $nombre"

    compteur1=$(($nb/$X))
    echo "Nombre de paquet de $X mails : $compteur1 paquets + 1 paquet des mails restants"
    echo
    echo "Regroupement des mails pour créer les archives"
    echo
    echo "Veuillez patienter ..."
    echo

    compteur2=$((compteur1+1))

    i=$((0))
    while [ $i -lt $compteur2 ]
    do
    nb_fic=$(($i*$X));
    fin_fic=$(($nb_fic+$X));
    j=$(($nb_fic))
    while [ $j -lt $fin_fic ]
    do
    if test -f "/tmp/mboxout$j.txt"
    then cat /tmp/mboxout$j.txt >> archive$i;
    fi
    true $((j++))
    done;
    true $((i++))
    done

    rm /tmp/mboxout*.txt

    echo "Les fichiers archives suivants ont été créés :"
    ls -x archive*
    echo
    mv archive* $3
    echo "Ils ont été sauvés dans : $3/"
    echo

    date_fin=$(date)
    echo "** fin de traitement : $date_fin **"
    exit 0
    0