Добавьте файлы в zip-архив, пропуская существующие файлы, с помощью команды zip

Вопрос или проблема

Можно ли пропустить существующие файлы при добавлении файлов в существующий архив с помощью команды zip?

zip -u добавляет только изменённые или новые файлы, но мне нужно добавить только новые файлы, пропуская ‘изменённые’.

Контекст (хотя это должно быть несущественным): у меня есть zip архив, созданный другим процессом, и я хочу добавить стандартные файлы, если они отсутствуют (не перезаписывать изменённые файлы стандартными).

Извлечение названий файлов из zip архива является сложной задачей, поэтому используйте следующее с осторожностью; это будет обрабатывать только названия файлов, которые не содержат пробелов или табуляций (никаких символов из $IFS).

Первый метод использует цикл с grep, чтобы спросить для каждого запрашиваемого файла, существует ли он уже в архиве; если нет, цикл добавляет этот файл в архив.

Второй метод выполняет одну команду zip, но говорит zip исключить файлы, которые уже находятся в архиве, с помощью опции -x.

zipaddgrep() {
  ziparchive=$1
  shift
  for arg
  do
    if ! zipinfo -1 "$ziparchive" | grep -Fqx "$arg"
    then
        zip "$ziparchive" "$arg"
    fi
  done
}

zipaddexclude() {
  ziparchive=$1
  shift
  zip -u "$ziparchive" "$@" -x $(zipinfo -1 "$ziparchive")
}

Для демонстрации:

# настройка
mkdir ~/tmp/472017
cd ~/tmp/472017
mkdir thefiles
date > thefiles/file1
date > thefiles/file2
date > thefiles/file3
zip zipfile thefiles/file{1,2}

# метод 1
$ set -x
$ zipaddgrep zipfile.zip thefiles/*
+ zipaddgrep zipfile.zip thefiles/file1 thefiles/file2 thefiles/file3
+ ziparchive=zipfile.zip
+ shift
+ for arg in '"$@"'
+ grep --color=auto -Fqx thefiles/file1
+ zipinfo -1 zipfile.zip
+ for arg in '"$@"'
+ grep --color=auto -Fqx thefiles/file2
+ zipinfo -1 zipfile.zip
+ for arg in '"$@"'
+ grep --color=auto -Fqx thefiles/file3
+ zipinfo -1 zipfile.zip
+ zip zipfile.zip thefiles/file3
  добавление: thefiles/file3 (хранится 0%)

# очистка
rm zipfile.zip
zip zipfile thefiles/file{1,2}

# метод 2
$ zipaddexclude zipfile.zip thefiles/*
+ zipaddexclude zipfile.zip thefiles/file1 thefiles/file2 thefiles/file3
+ ziparchive=zipfile.zip
+ shift
++ zipinfo -1 zipfile.zip
+ zip -u zipfile.zip thefiles/file1 thefiles/file2 thefiles/file3 -x thefiles/file1 thefiles/file2
  добавление: thefiles/file3 (хранится 0%)

Ответ или решение

Как добавить файлы в zip-архив, пропуская существующие файлы с помощью команды zip

Вопрос о том, как добавить файлы в существующий zip-архив, пропуская измененные или уже присутствующие файлы, вполне актуален для многих специалистов в IT. Стандартная команда zip -u добавляет только измененные или новые файлы, что не соответствует вашим требованиям. В данном ответе мы рассмотрим два метода, которые помогут вам достигнуть желаемого результата.

Метод 1: Использование цикла с grep

Первым методом является применение цикла вместе с инструментом grep, который проверяет, присутствуют ли файлы в архиве до их добавления. Если файл отсутствует, он добавляется в архив. Следующий код реализует это решение:

zipaddgrep() {
  ziparchive=$1
  shift
  for arg
  do
    if ! zipinfo -1 "$ziparchive" | grep -Fqx "$arg"
    then
        zip "$ziparchive" "$arg"
    fi
  done
}

В этом методе функция zipaddgrep принимает имя архива в качестве первого аргумента и потом – файлы, которые нужно добавить. Мы используем zipinfo -1 для получения списка файлов в архиве, версия grep с параметрами -Fqx позволяет делать проверку на наличие точного совпадения.

Метод 2: Исключение с помощью флага -x

Вторым методом является использование флага -x для исключения файлов, которые уже находятся в архиве. Данный подход более эффективен, так как позволяет выполнить одну команду zip без необходимости явного перебора файлов. Код для этого метода выглядит так:

zipaddexclude() {
  ziparchive=$1
  shift
  zip -u "$ziparchive" "$@" -x $(zipinfo -1 "$ziparchive")
}

Здесь мы сначала получаем имена уже включенных в архив файлов с помощью zipinfo -1, а затем передаем их в команду zip с использованием флага -x, что позволяет исключить их из добавления.

Пример использования

Для демонстрации обеих функций мы создадим временную директорию и zip-архив, а затем протестируем оба метода:

# Настройка среды
mkdir ~/tmp/472017
cd ~/tmp/472017
mkdir thefiles
date > thefiles/file1
date > thefiles/file2
date > thefiles/file3
zip zipfile thefiles/file{1,2}

# Метод 1
zipaddgrep zipfile.zip thefiles/*

# Метод 2
zipaddexclude zipfile.zip thefiles/*

После выполнения этих команд файловые операции будут обработаны в соответствии с вашими требованиями: файлы добавятся только если их нет в архиве, что обеспечит сохранность существующих и измененных данных.

Заключение

Использование представленных методов позволяет легко управлять содержимым zip-архивов, добавляя в них только необходимые файлы и избегая перезаписывания измененных. Эти процедуры имеют широкое применение в сферах резервного копирования и автоматизации, что делает их полезными инструментами для IT-специалистов и системных администраторов. Выбирайте способ, который больше соответствует вашим требованиям, и эффективными методами управляйте вашими zip-архивами.

Оцените материал
Добавить комментарий

Капча загружается...