ファイル数に基づいて zip アーカイブを作成する

ファイル数に基づいて zip アーカイブを作成する

サンOS5.8

ディレクトリ構造

/テスト/CHM

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

親ディレクトリ CHM に 8 個未満のファイル/サブディレクトリがある場合は、通常どおり zip で圧縮します。親ディレクトリ CHM に 8 個以上のファイル/サブディレクトリがある場合は、5 つのファイルごとに zip アーカイブを作成します。これはテスト専用です。実稼働環境では、5 個ではなく 10000 個のファイルになります。親ディレクトリ CHM には、0 個から n 個のサブディレクトリを含めることができます。

#!/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)

2 番目の if ステートメントの else 部分が失敗していますが、その理由はわかりません。以下を作成しようとしています:

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

したがって、リモート サーバー上で同じ順序で解凍できます。

答え1

あなたのルールに完全に従ったかどうかはわかりませんが、標準ユーティリティを使用する方が簡単かもしれません(そして、何をいつ作成するかについてのルールを簡素化します)。

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

findは明らかなので、好みに合わせてオプションを調整してください。出力を に渡す前にリストをソートしたい場合がありますsplit

split:

  • - d- アルファベットの接尾辞の代わりに番号を使用する
  • -a3- 接尾辞の長さ(番号付け) 3桁(この場合は数字)
  • -l- カウンターを増やす行数
  • --filter=COMMAND- ファイルに書き込む代わりにコマンドに行を渡す
  • COMMAND- は通常書き込みに使用されるファイル名として$FILE解釈されるsplitため、一重引用符で囲む必要があります(または、上記のコマンドラインを実行するシェルによる解釈を防ぐためにバックスラッシュで囲む必要があります)。
  • -- 標準入力の解析を明示的に要求する
  • "$pfx".好みのプレフィックス。ドットは意図的なものであり、split自動的に追加されるものではありません。

答え2

Sun Solaris で動作するソリューションがあります。これは、各マルチパート zip ごとに 10000 個のファイルを圧縮し、マスター zip をリモート サーバーに scp します。

#!/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

関連情報