[Shell] dividir archivos grandes de la bandeja de entrada de forma limpia

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

2 respuestas

  1. wolfen
     
    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 
    0
  2. wolfen13fr Mensajes publicados 1 Estado Miembro
     
    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
    0