![Crear un archivo zip según la cantidad de archivos](https://rvso.com/image/89166/Crear%20un%20archivo%20zip%20seg%C3%BAn%20la%20cantidad%20de%20archivos.png)
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".
find
Es 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 archivoCOMMAND
-$FILE
se interpretasplit
como 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,split
no 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