2

Мой вопрос такой же, как в Создание нескольких файлов ZIP, которые не зависят друг от друга? но моя идея состоит в том, чтобы добавлять файлы в zip, пока он не достигнет необходимого размера, и продолжить с новым zip файлом для других и так далее.

Любая идея, как сделать это в сценарии bas? Сценарий здесь, https://superuser.com/questions/614176/creating-a-bash-script-zipping, кажется, очень помогает. Требуются некоторые настройки, хотя.

2 ответа2

3

Базовый скрипт просто проверяет размер zip-файла и соответственно переключает zip-файлы. Что-то вроде этого:


#!/usr/bin/env bash

## This counter is used to change the zip file name
COUNTER=0;
## The maximum size allowed for the zip file
MAXSIZE=1024;
## The first zip file name
ZIPFILE=myzip"$COUNTER".zip;
## Exit if the zip file exists already
if [ -f $ZIPFILE ]; then
    echo $ZIPFILE exists, exiting...
    exit;
fi
## This will hold the zip file's size, initialize to 0
SIZE=0;

## Go through each of the arguments given in the command line
for var in "$@"; do
    ## If the zip file's current size is greater than or
    ## equal to $MAXSIZE, move to the next zip file
    if [[ $SIZE -ge $MAXSIZE ]]; then
    let COUNTER++;
    ZIPFILE=myzip"$COUNTER".zip;
    fi
    ## Add file to the appropriate zip file
    zip -q $ZIPFILE $var;
    ## update the $SIZE
    SIZE=`stat -c '%s' $ZIPFILE`;
done

ПРЕДОСТЕРЕЖЕНИЯ:

  • Сценарий ожидает файлы, а не каталоги, если вы хотите, чтобы он запускался в каталогах, добавьте -r к команде zip . Однако он не будет проверять размер файла, пока каждый каталог не будет сжат.
  • Размер файла zip проверяется после каждого сжатия. Это означает, что вы получите файлы, размер которых превышает ваш лимит. Это потому, что трудно угадать, каким будет сжатый размер файла, поэтому я не могу проверить его перед добавлением в архив.
0

РЕДАКТИРОВАТЬ: Есть идеи об оптимизации приведенного ниже сценария для большого количества файлов?

#!/usr/bin/env bash

format="%b-%m.zip"    # the default format
# see http://unixhelp.ed.ac.uk/CGI/man-cgi?date
dateformat="%Y-%b-%d" # the default date format
zipsize=2048; #256901120 #245MB
zipfile="" # the zip file name to use.

if [[ $# -lt 1 ]]; then
  echo "Usage: $0 directory [format] [zip size] [dateformat]"
  echo
  echo "Where format can include the following variables:"
  echo " %f file"
  echo " %b file with no extention"
  echo " %e file extention"
  echo " %c file created date (may be 1-Jan-1970 UTC if unknown)"
  echo " %m file modified date"
  echo " %t current date"
  echo
  echo "And dateformat uses the same format specifiers as the date command."
  echo
  echo " Example: $0 zip-1 %f-%m.zip %Y"
  echo " Example: $0 zip-1 %f-%m.zip %Y-%b"
  echo
  echo "And zipsize is the maximum zip size allowed per zip file in bytes."
  echo
  echo " Example: $0 zip-1 256901120 %f-%m.zip %Y"
  echo " Example: $0 zip-1 256901120 %f-%m.zip %Y-%b"
  exit 1
fi

if [[ $# -ge 2 ]]; then
  zipsize="$2"
fi

if [[ $# -ge 3 ]]; then
  format="$3"
fi

if [[ $# -ge 4 ]]; then
  dateformat="$4"
fi


dozip()
{
  filepath=$1
  parent_path=$(dirname "$filepath")
  file=$(basename "$filepath")
  ext=${file##*.}
  body=${file%.*}

  date=$(date +$dateformat)
  mdate=$(date --date="@$(stat -c %Y "$filepath")" +$dateformat)
  cdate=$(date --date="@$(stat -c %W "$filepath")" +$dateformat)

    if [ -z "$zipfile" ]; then
    zipfile=$(echo $format | sed -e "s/%f/$file/g" -e "s/%b/$body/g" -e "s/%e/$ext/g" -e "s/%t/$date/g" -e "s/%m/$mdate/g" -e "s/%c/$cdate/g")
    else
    size=`stat -c '%s' $zipfile`
    if [[ $size -ge $zipsize ]]; then
      zipfile=$(echo $format | sed -e "s/%f/$file/g" -e "s/%b/$body/g" -e "s/%e/$ext/g" -e "s/%t/$date/g" -e "s/%m/$mdate/g" -e "s/%c/$cdate/g")
    fi
    fi

  pushd "$parent_path" > /dev/null
  zip "$zipfile" "$file" > /dev/null
  popd > /dev/null
}

#files=$(find $1 -type f)
files=$(find $1 -type f | sed -e '/zip$/d') # exclude zip files
IFS=$'\n';
for file in $files; do
  dozip $file
done

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .