[Shell] dividir archivos grandes de la bandeja de entrada de forma limpia
wolfen
-
wolfen13fr Mensajes publicados 1 Estado Miembro -
wolfen13fr Mensajes publicados 1 Estado Miembro -
Hola,
Rara vez, tenemos usuarios que dejan que su archivo Inbox en Thunderbird se “ hinche ” y llega a la límite de 4 GB.
La solución que he encontrado hasta ahora es dividir manualmente el archivo en varios archivos de 1 000 000 de líneas (aprox. 740 MB por archivo) y luego unir el final del primer archivo con el inicio del segundo para reconstruir el último correo del archivo cortado, el final del segundo con el inicio del tercero, etc.
Creo que es factible automatizar todo esto con un script en shell.
Ya sé cómo dividir mi archivo en varias piezas:
split -1000000 Inbox archive
Con eso obtengo 6 archivos llamados “archiveaa”, “archiveab”, …, “archiveaf”.
Esta parte es fácil... En cuanto a la parte de ajuste, no sé muy bien cómo hacerlo.
Sé que un mensaje en un archivo Inbox empieza con el esquema “From - ”. Pero ¿cómo decirle al script que tome la última ocurrencia de ese esquema, que corte lo que sigue y que lo pegue al inicio del archivo siguiente para reconstruir el mensaje? Ahí es donde me bloqueo.
¿Usar sed o awk? ¿Alguien tiene una pista para la segunda parte?
¡Gracias de antemano!
Rara vez, tenemos usuarios que dejan que su archivo Inbox en Thunderbird se “ hinche ” y llega a la límite de 4 GB.
La solución que he encontrado hasta ahora es dividir manualmente el archivo en varios archivos de 1 000 000 de líneas (aprox. 740 MB por archivo) y luego unir el final del primer archivo con el inicio del segundo para reconstruir el último correo del archivo cortado, el final del segundo con el inicio del tercero, etc.
Creo que es factible automatizar todo esto con un script en shell.
Ya sé cómo dividir mi archivo en varias piezas:
split -1000000 Inbox archive
Con eso obtengo 6 archivos llamados “archiveaa”, “archiveab”, …, “archiveaf”.
Esta parte es fácil... En cuanto a la parte de ajuste, no sé muy bien cómo hacerlo.
Sé que un mensaje en un archivo Inbox empieza con el esquema “From - ”. Pero ¿cómo decirle al script que tome la última ocurrencia de ese esquema, que corte lo que sigue y que lo pegue al inicio del archivo siguiente para reconstruir el mensaje? Ahí es donde me bloqueo.
¿Usar sed o awk? ¿Alguien tiene una pista para la segunda parte?
¡Gracias de antemano!
2 respuestas
-
Me auto-respondo, después de dos días de investigación y de ajustar cosas...
Aquí hay un script un poco complicado pero que funciona en Linux (Ubuntu 10.04 LTS) :
#!/bin/sh # script shell "decoupagembox.sh" versión Linux - Ubuntu 10.04 LTS # # Este script corta un archivo en formato mbox en varios archivos/archivos. # El número de correos por archivo es configurable. El tamaño de cada archivo # dependerá del peso de los correos y por tanto de los adjuntos vinculados. # febrero 2011 # código bajo licencia Creative Commons by-nc-sa (difusión libre y modificable # citando al autor original y sin uso comercial # # autor : Damien MAURAN, # dmauran@gmail.com echo "Découpage d'un fichier format mbox en plusieurs archives ..." echo if test "$1" = "" then echo "Indique el nombre del archivo a tratar, el número de correos por archivo" echo "y la ruta de destino. Ejemplo :" echo echo "decoupagembox.sh nom_fichier_source xx chemin_de_destination/" echo echo "donde xx es el número de correos por archivo. Si xx no se indica," echo "el valor por defecto será de 500 correos por archivo." echo echo "Fin del script ... sin procesamiento." exit 0 fi if test "$3" = "" then echo "Indique el nombre del archivo a tratar, el número de correos por archivo" echo "y la ruta de destino. Ejemplo :" echo echo "decoupage.sh nom_fichier xx chemin_de_destination/" echo echo "donde xx es el número de correos por archivo. Si xx no se indica," echo "el valor por defecto será de 500 correos por archivo." echo echo "Fin del script ... sin procesamiento." exit 0 fi if test "$2" = "" then X=$((500)) else X=$(($2)) fi date_debut=$(date) echo "** Inicio de procesamiento : $date_debut **" echo echo "isolación de correos: 1 correo = 1 archivo" echo echo "Por favor, espere, esto puede tomar un tiempo ..." 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 "Número de correos extraídos: $nombre" compteur1=$(($nb/$X)) echo "Número de paquetes de $X correos: $compteur1 paquetes + 1 paquete de correos restantes" echo echo "Agrupación de correos para crear los archivos" echo echo "Por favor, espere ..." 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 "Los archivos de archivo siguientes han sido creados :" ls -x archive* echo mv archive* $3 echo "Han sido guardados en : $3/" echo date_fin=$(date) echo "** fin de procesamiento : $date_fin **" exit 0
Y por si fuera necesario, el mismo código pero optimizado para Mac OS X (versión 10.6.5) :#!/bin/sh # script shell "decoupagembox.sh" versión Mac OS X (versión 10.6.5) # # Este script corta un archivo en formato mbox en varios archivos/archivos. # El número de correos por archivo es configurable. El tamaño de cada archivo # dependerá del peso de los correos y por tanto de los adjuntos vinculados. # febrero 2011 # código bajo licencia Creative Commons by-nc-sa (difusión libre y modificable # citando el autor original y sin uso comercial # # autor : Damien MAURAN, # dmauran@gmail.com echo "Découpage d'un fichier format mbox en plusieurs archives ..." echo if test "$1" = "" then echo "Indique el nombre del archivo a tratar, el número de correos por archivo" echo "y la ruta de destino. Ejemplo :" echo echo "decoupage.sh nom_fichier xx chemin_de_destination/" echo echo "donde xx es el número de correos por archivo. Si xx no se indica," echo "la valor por defecto será de 500 correos por archivo." echo echo "Fin del script ... sin procesamiento." exit 0 fi if test "$3" = "" then echo "Indique el nombre del archivo a tratar, el número de correos por archivo" echo "y la ruta de destino. Ejemplo :" echo echo "decoupage.sh nom_fichier xx chemin_de_destination/" echo echo "donde xx es el número de correos por archivo. Si xx no se indica," echo "la valor por defecto será de 500 correos por archivo." echo echo "Fin del script ... sin procesamiento." exit 0 fi if test "$2" = "" then X=$((500)) else X=$(($2)) fi date_debut=$(date) echo "** Inicio de procesamiento : $date_debut **" echo echo "isolación de correos: 1 correo = 1 archivo" echo echo "Por favor, espere, esto puede tomar un tiempo ..." 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 "Número de correos extraídos: $nombre" compteur1=$(($nb/$X)) echo "Número de paquetes de $X correos: $compteur1 paquetes + 1 paquete de correos restantes" echo echo "Agrupación de correos para crear los archivos" echo echo "Por favor, espere ..." 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 "Los archivos de archivo siguientes han sido creados :" ls -x archive* echo mv archive* $3 echo "Han sido guardados en : $3/" echo date_fin=$(date) echo "** fin de procesamiento : $date_fin **" exit 0 -
Me autocontesto, después de dos días de búsqueda y de pruebas…
Aquí hay un script un poco elaborado pero que funciona bajo Linux (Ubuntu 10.04 LTS) :
#!/bin/sh
# script shell "decoupagembox.sh" versión Linux - Ubuntu 10.04 LTS
#
# Este script corta un archivo en formato mbox en varios archivos.
# El número de correos por archivo es configurable. El tamaño de cada archivo
# dependerá del peso de los correos y por tanto de los adjuntos vinculados.
# febrero 2011
# código bajo licencia Creative Commons by-nc-sa (difusión libre y modificable
# citando al autor original y sin uso comercial
#
# autor: Damien MAURAN,
echo "Corte de un archivo formato mbox en múltiples archivos..."
echo
if test "$1" = ""
then echo "Indica el nombre del archivo a procesar, el número de correos por archivo"
echo "y la ruta de destino. Ejemplo :"
echo
echo "decoupagembox.sh nom_fichier_source xx chemin_de_destination/"
echo
echo "donde xx es el número de correos por archivo. Si xx no se indica,"
echo "el valor por defecto será de 500 correos por archivo."
echo
echo "Fin del script ... ningún procesamiento realizado."
exit 0
fi
if test "$3" = ""
then echo "Indica el nombre del archivo a procesar, el número de correos por archivo"
echo "y la ruta de destino. Ejemplo :"
echo
echo "decoupage.sh nom_fichier xx chemin_de_destination/"
echo
echo "donde xx es el número de correos por archivo. Si xx no se indica,"
echo "el valor por defecto será de 500 correos por archivo."
echo
echo "Fin del script ... ningún procesamiento realizado."
exit 0
fi
if test "$2" = ""
then X=$((500))
else
X=$(($2))
fi
date_debut=$(date)
echo "** Inicio del procesamiento : $date_debut **"
echo
echo "isolation des emails : 1 email = 1 fichier"
echo
echo "Por favor, tenga paciencia, esto puede tomar tiempo ..."
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 "Número de correos extraídos : $nombre"
compteur1=$(($nb/$X))
echo "Número de paquetes de $X correos : $compteur1 paquetes + 1 paquete de correos restantes"
echo
echo "Agrupando correos para crear los archivos"
echo
echo "Por favor, espere..."
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 "Los archivos de archivo siguientes han sido creados :"
ls -x archive*
echo
mv archive* $3
echo "Han sido guardados en : $3/"
echo
date_fin=$(date)
echo "** fin del procesamiento : $date_fin **"
exit 0
Et voici le même code mais optimisé pour Mac OS X (versión 10.6.5) :
#!/bin/sh
# script shell "decoupagembox.sh" versión Mac OS X (versión 10.6.5)
#
# Este script corta un archivo en formato mbox en varios archivos.
# El número de correos por archivo es configurable. El tamaño de cada archivo
# dependerá del peso de los correos y por tanto de los adjuntos vinculados.
# febrero 2011
# código bajo licencia Creative Commons by-nc-sa (difusión libre y modificable
# citando al autor original y sin uso comercial
#
# autor : Damien MAURAN,
# dmauran@gmail.com
echo "Corte de un archivo formato mbox en múltiples archivos..."
echo
if test "$1" = ""
then echo "Indica el nombre del archivo a procesar, el número de correos por archivo"
echo "y la ruta de destino. Ejemplo :"
echo
echo "decoupage.sh nom_fichier xx chemin_de_destination/"
echo
echo "donde xx es el número de correos por archivo. Si xx no se indica,"
echo "el valor por defecto será de 500 correos por archivo."
echo
echo "Fin del script ... ningún procesamiento realizado."
exit 0
fi
if test "$3" = ""
then echo "Indica el nombre del archivo a procesar, el número de correos por archivo"
echo "y la ruta de destino. Ejemplo :"
echo
echo "decoupage.sh nom_fichier xx chemin_de_destination/"
echo
echo "donde xx es el número de correos por archivo. Si xx no se indica,"
echo "el valor por defecto será de 500 correos por archivo."
echo
echo "Fin del script ... ningún procesamiento realizado."
exit 0
fi
if test "$2" = ""
then X=$((500))
else
X=$(($2))
fi
date_debut=$(date)
echo "** Inicio del procesamiento : $date_debut **"
echo
echo "isolation des emails : 1 email = 1 fichier"
echo
echo "Por favor, tenga paciencia, esto puede tomar tiempo ..."
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 "Número de correos extraídos : $nombre"
compteur1=$(($nb/$X))
echo "Número de paquetes de $X correos : $compteur1 paquetes + 1 paquete de correos restantes"
echo
echo "Agrupando correos para crear los archivos"
echo
echo "Por favor, espere ..."
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 "Los archivos de archivo siguientes han sido creados :"
ls -x archive*
echo
mv archive* $3
echo "Han sido guardados en : $3/"
echo
date_fin=$(date)
echo "** fin del procesamiento : $date_fin **"
exit 0