파일 수에 따라 zip 아카이브 생성

파일 수에 따라 zip 아카이브 생성

썬 OS 5.8

디렉토리 구조

/테스트/chm

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

상위 디렉터리 CHM에 8개 미만의 파일/하위 디렉터리가 있으면 압축이 정상입니다. 상위 디렉터리 CHM에 8개 이상의 파일/하위 디렉터리가 있는 경우 5개 파일에 대한 zip 아카이브를 만듭니다. 이는 테스트용으로만 사용됩니다. 프로덕션에서는 5개가 아닌 10,000개의 파일이 됩니다. 상위 디렉터리 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)

두 번째 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

관련 정보