Как удалить содержимое папок перед распаковкой большого количества молний? (сценарий bash)

#bash #zip #unzip

Вопрос:

У меня есть много папок на FTP с их содержимым, и некоторые из них я должен время от времени обновлять. Я обновляю их, распаковывая полученные zip-файлы. Имена zip-файлов могут быть разными, но в zip всегда есть основная папка с точно таким же именем папки, которую следует обновить на FTP. Больше никаких других файлов/папок в ZIP-файлах, кроме основной папки с ее содержимым. Поэтому я написал простой скрипт ниже, чтобы обновить их:

 unzip -o *.zip
rm -f *.zip
 

Проблема в том, что иногда в этих папках есть файлы, которые следует удалить — они больше не существуют в архивах с обновлениями. И я понял, что когда я распаковываю и перезаписываю, ничего не удаляется из того, что должно быть. Можно ли изменить этот скрипт, чтобы удалить целую папку перед распаковкой, чтобы быть уверенным? Правильное имя папки для обновления-это не имя zip, а имя основной папки в zip, и из-за этого я не знаю, как это решить. Я не мог найти существующего решения для этого. Кроме того, иногда я загружаю сразу много zip-файлов, а на FTP есть тысячи папок, поэтому было бы трудно написать одну команду для каждой отдельной папки.

Комментарии:

1. Почему вы упомянули FTP. Играет ли FTP какую-либо роль в вашей проблеме вообще или это была бы та же проблема, если бы вы получали zip-архивы из другого источника?

Ответ №1:

Вы можете использовать unzip сопутствующую программу zipinfo для просмотра содержимого zip-файлов. Добавьте шаблон */ в список только каталогов. Затем трубу xargs , чтобы удалить их.

 zipinfo -1 '*.zip' '*/' | xargs rm -rf 2>/dev/null
 

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

Вы могли бы добавить cut -d / -f 1 | sort -u | раньше xargs , чтобы отфильтровать любые подкаталоги rm , но это не должно иметь значения, даже если они есть.

xargs разделяет строки пробелами, поэтому имя каталога, содержащее пробелы, может привести к удалению другого каталога. Для GNU xargs вы можете добавить --delimiter='n' , чтобы остановить это (есть также --null , но zip все равно обрезает новые строки в именах файлов). Вы также можете просто исключить каталоги, содержащие пробелы, с помощью конвейера grep -v '[[:space:]]' .

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

 for zip in *.zip; do
    dirs=$(zipinfo -1 "$zip" '*/') || continue
    IFS=

Этот метод также подходит для пробелов. Разделение  dirs  на массив просто означает rm  , что оно все равно будет успешным, если в архиве есть более одного каталога. Если  zipinfo  это не удается, это, вероятно, означает, что архив поврежден или нечитаем, следовательно  || continue  . Вы можете удалить это, если хотите попробовать извлечение в любом случае.



n' read -rd '' -a dirs<<<"$dirs"

rm -rf "${dirs[@]}"
unzip -o "$zip"
done
Этот метод также подходит для пробелов. Разделение dirs на массив просто означает rm , что оно все равно будет успешным, если в архиве есть более одного каталога. Если zipinfo это не удается, это, вероятно, означает, что архив поврежден или нечитаем, следовательно || continue . Вы можете удалить это, если хотите попробовать извлечение в любом случае.