SunOS 5.8
Verzeichnisaufbau
/TEST/CHM
CHM
A
file1.txt
file2.txt
B
file3.txt
C
file4.txt
file5.txt
file6.txt
Wenn das übergeordnete Verzeichnis CHM weniger als 8 Dateien/Unterverzeichnisse hat, komprimieren Sie es normal. Wenn das übergeordnete Verzeichnis CHM 8 oder mehr Dateien/Unterverzeichnisse hat, erstellen Sie ein Zip-Archiv für jeweils 5 Dateien. Dies dient nur zu Testzwecken. In der Produktion werden es 10.000 Dateien sein, nicht 5. Das übergeordnete Verzeichnis CHM kann 0 bis n Unterverzeichnisse haben.
#!/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)
Der else-Teil der zweiten if-Anweisung schlägt fehl und ich bin mir nicht sicher, warum. Ich möchte Folgendes erstellen:
CHM.zip master
CHM.001.zip
CHM.002.zip
CHM.003.zip
So kann ich die Dateien in der gleichen Reihenfolge auf einem Remote-Server entpacken.
Antwort1
Ich bin nicht ganz sicher, ob ich Ihre Regeln vollständig befolgt habe, aber es könnte einfacher sein, Standarddienstprogramme zu verwenden (und die Regeln dafür zu vereinfachen, was und wann erstellt werden soll):
find . -type f | split -d -a3 -l $num --filter='zip -@ $FILE.zip' - "$pfx".
find
ist ziemlich offensichtlich, passen Sie die Optionen nach Ihren Wünschen an. Möglicherweise möchten Sie die Liste sortieren, bevor Sie ihre Ausgabe an weitergeben split
.
split
:
- d
- Nummerierung statt alphabetischer Suffixe verwenden-a3
- Länge des Suffixes (der Nummerierung) 3 Stellen (in diesem Fall Ziffern)-l
- Anzahl der Zeilen, nach denen der Zähler erhöht werden soll--filter=COMMAND
- Zeilen an einen Befehl übergeben, anstatt sie in eine Datei zu schreibenCOMMAND
-$FILE
wird als Dateiname interpretiertsplit
, der normalerweise zum Schreiben verwendet wird, was bedeutet, dass er in einfache Anführungszeichen gesetzt werden muss (oder mit einem Backslash, um eine Interpretation durch die Shell zu verhindern, die die obige Befehlszeile ausführt)-
- erfordert ausdrücklich das Parsen der Standardeingabe"$pfx".
Ihr bevorzugtes Präfix. Der Punkt ist beabsichtigt undsplit
wird nicht automatisch angehängt.
Antwort2
Ich habe eine Lösung, die unter Sun Solaris funktioniert. Dabei werden 10.000 Dateien pro mehrteiligem Zip komprimiert und das Master-Zip per SCP auf den Remote-Server übertragen.
#!/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