Вопрос или проблема
Можно ли пропустить существующие файлы при добавлении файлов в существующий архив с помощью команды 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-архивами.