[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 !
A voir également:

2 réponses

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
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