Crear un archivo zip según la cantidad de archivos

Crear un archivo zip según la cantidad de archivos

Sun OS 5.8

Estructura de directorios

/PRUEBA/CHM

CHM
   A
     file1.txt
     file2.txt
   B
     file3.txt
   C
     file4.txt
     file5.txt
     file6.txt

Si el directorio principal CHM tiene menos de 8 archivos/subdirectorios, comprímalo normalmente. Si el directorio principal CHM tiene 8 o más archivos/subdirectorios, cree un archivo zip para cada 5 archivos. Esto es sólo para pruebas. En producción serán 10000 archivos, no 5. El directorio principal CHM podría tener de 0 a n subdirectorios.

#!/bin/bash
set -e

cd $subdir/

# vars
num=8  # set 10000 in production

for dir in $subdir
do
    dir=${dir%*/}

    # testing code only
          if [[ ${dir##*/} = "CHM" ]]
          then
                numfile=$(ls * | wc -l)
          fi

          if [ "$numfile" -lt "$num" ]
          then
               zip -r -6 ${dir##*/}.zip .
          else
               ls * > files
               split -l 5 - files < files
               for i in files[a-z][a-z]; do
                   zip -6 "$i.zip" -@ < "$i"
               done
          fi
    # end test
done
exit


   zip warning: name not matched: A:
   zip warning: name not matched: file1.txt
   zip warning: name not matched: file2.txt
   zip warning: name not matched: B:

zip error: Nothing to do! (filesaa.zip)

La otra parte de la segunda declaración if falla y no estoy seguro de por qué. Estoy buscando crear:

CHM.zip master
CHM.001.zip
CHM.002.zip
CHM.003.zip

Entonces puedo descomprimir en el mismo orden en un servidor remoto.

Respuesta1

No estoy del todo seguro de haber seguido sus reglas por completo, pero podría ser más fácil usar utilidades estándar (y simplificar las reglas sobre qué y cuándo crear):

find . -type f | split -d -a3 -l $num --filter='zip -@ $FILE.zip' - "$pfx".

findEs bastante obvio, modifica las opciones a tu gusto. Es posible que desee ordenar la lista antes de pasar su salida a split.

split:

  • - d- utilizar numeración en lugar de sufijos alfabéticos
  • -a3- longitud del sufijo (la numeración) 3 lugares (dígitos en este caso)
  • -l- número de líneas después de las cuales aumentar el contador
  • --filter=COMMAND- pasar líneas a un comando en lugar de escribir en un archivo
  • COMMAND- $FILEse interpreta splitcomo un nombre de archivo que normalmente se usaría para escribir, lo que significa que debe estar entre comillas simples (o con una barra invertida para evitar la interpretación por parte del shell que ejecuta la línea de comando anterior).
  • -- requiere explícitamente el análisis de la entrada estándar
  • "$pfx".su prefijo preferido. El punto es intencional, splitno se agrega automáticamente.

Respuesta2

Tengo la solución que funciona en Sun Solaris. Esto comprimirá 10000 archivos por cada zip de varias partes y enviará el zip maestro al servidor remoto.

#!/usr/bin/env bash
#
#------------------------------------------------------------
#-- Zip up content files based on $1 parameter
#------------------------------------------------------------
function zip_files {
   SRC="/ads/data02/CTS/Data/$1"
   #-- destination folder
   DST="/ads/acct/oracle/CTS"
   #-- amount of files that should go in each zip file
   FILES_PER_ZIP=10000

#-----------------------------------------------------------

  FILES="/tmp/multizip.$$"
  ZIP_PREFIX=$(basename $SRC)

#-- generate the list of the files to zip
  find $SRC > $FILES

#-- zip the files
  NUM=0
  ZIP_NUM=1
  printf -v ZIPFILE "$DST/$ZIP_PREFIX%03d" $ZIP_NUM
  while read -r line; do
    echo $line | sed -e 's/.*/"&"/' | xargs zip -6 $ZIPFILE
    ((NUM++))
    if [ $NUM -eq $FILES_PER_ZIP ]; then
       NUM=0
       ((ZIP_NUM++))
       printf -v ZIPFILE "$ZIP_PREFIX%03d" $ZIP_NUM
    fi
done < $FILES

#-- generate master zip file
/usr/bin/ls $DST/${ZIP_PREFIX}*.zip | xargs zip $DST/$ZIP_PREFIX

#-- perform cleanup

   function finish {
     /usr/bin/rm $FILES
     /usr/bin/rm /ads/acct/oracle/CTS/${ZIP_PREFIX}[0-9][0-9][0-9].zip
   }

   trap finish EXIT
}


#------------------------------------------------------------
#-- Main processing
#------------------------------------------------------------

for dir in /ads/data02/CTS/Data/*/
do
    d=$(basename $dir)
    zip_files $d
    scp "/ads/acct/oracle/CTS/${d}.zip" [email protected]:/var/www/html/CTS/Content/A/TMP
    /usr/bin/rm -f "/ads/acct/oracle/CTS/${d}.zip"
done
exit

información relacionada