Архивировать вместе файлы с именами файлов, которые рекурсивно совпадают по каталогам

#bash #unix #terminal #find #zip

#bash #unix #терминал #Найти #zip

Вопрос:

Рассмотрим файловую систему следующим образом:

 folderA
   - one.png
   - two.png
   - three.png

folderB
   - one.png
   - two.png
   - three.png

folderC
   - one.png
   - two.png
   - three.png
  

Я хочу объединить все .png, которые совпадают one.png , в ZIP-файл one.zip с именем . Важно отметить, что он должен искать только конкретные имена файлов, а не заглядывать внутрь файлов, потому что код, который генерирует эти .png, существует, и я не хочу сопоставлять что-либо, что не является фактическим .png .

Я попытался выполнить поиск, но с помощью ключевых слов, которые я знаю, я получаю много результатов поиска в ZIP-файле.

Я на OSX Mojave. Был бы признателен за любую помощь!

Спасибо, Адхи

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

1. Бонусные баллы за скрипт, который будет создавать архивы для всех one , two и three где я могу указать фактические имена файлов.

Ответ №1:

Ну, вы можете сойти с ума и поместить все one.png файлы в one.zip , все two.png файлы в two.zip и т. Д:

 for file in $( find -name *.png | sed 's:.*/::' | sort -u ); do
    zip $(basename $file .png).zip $( find -name $file )
done
  

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

1. for file in $(...); do ...; done а переменные без кавычек являются шаблонами anit.

2. Меня действительно не волнуют шаблоны и анти-шаблоны. Я могу раздражать еще больше людей, используя обратные кавычки вместо $(...) .

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

4. @EdMorton Я не очень хорошо разбираюсь в bash, не могли бы вы рассказать мне о рисках использования решения Джека с учетом анти-шаблона?

5.См. mywiki.wooledge.org/DontReadLinesWithFor, mywiki.wooledge.org/BashFAQ/001, и mywiki.wooledge.org/Quotes. Смотрите также mywiki.wooledge.org/BashGuide/Practices#Quoting и mywiki.wooledge.org/BashGuide/Practices#Don.27t_Ever_Do_These для получения дополнительной информации.

Ответ №2:

 base='one'
mapfile -t files < <(find . -name "${base}.png")
zip "${base}.zip" "${files[@]}"
  

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

1. Операционная система использует macOS Mojave, и версия bash , которая поставляется с ней (3.2.57 (1)-release), не содержит mapfile встроенной команды.

2. @user3439894 Я использую macOS High Sierra (предыдущую версию Mojave), и версия bash, которую я запускаю (4.4.12 (1)-release), содержит mapfile, поэтому я ожидаю, что он также доступен для операционной системы, даже если ей придется его установить.

3. macOS High Sierra поставляется с bash 3.2.57 (1)-release, и не все обновляют bash , как вы, очевидно, сделали. Суть, которую я пытаюсь донести, заключается в том, что вы дали ответ, который не работает на macOS, если вы не обновитесь до версии bash , которая содержит mapfile встроенную команду, и поэтому вы должны указать в своем ответе, что потребуется обновление bash . Вероятно, вам также следует указать, как это сделать.

4. Привет @EdMorton, так что ваше решение почти работает. Проблема в том, что она сохраняет структуру папок, окружающих файлы. Например, когда я пишу скрипт и запускаю его, я получаю zip-файл, который открывается и выглядит так: « FolderA -one.png FolderB -one.png FolderC -one.png « Я бы хотел, чтобы он отображался в папке, в которой есть только .png и ничего больше.