ZIP-Archiv basierend auf der Anzahl der Dateien erstellen

ZIP-Archiv basierend auf der Anzahl der Dateien erstellen

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".

findist 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 schreiben
  • COMMAND- $FILEwird als Dateiname interpretiert split, 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 und splitwird 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

verwandte Informationen