Рекурсивно найти все архивные файлы различных форматов и выполнить поиск по шаблонам имен файлов.

Рекурсивно найти все архивные файлы различных форматов и выполнить поиск по шаблонам имен файлов.

В лучшем случае я хотел бы услышать что-то вроде этого:

$searchtool /path/to/search/ -contained-file-name "*vacation*jpg"

... так что этот инструмент

  • выполняет рекурсивное сканирование указанного пути
  • принимает все файлы с поддерживаемыми форматами архивов, которые должны быть как минимум «наиболее распространенными», такими как zip, rar, 7z, tar.bz, tar.gz ...
  • и просканируйте список файлов архива на предмет наличия нужного шаблона имени (здесь *vacation*jpg)

Я знаю, как использовать find tool, tar, unzip и т. п. Я мог бы объединить их со скриптом оболочки, но я ищу простое решение, которое может быть однострочным shell или специализированным инструментом (подсказки по инструментам GUI приветствуются, но мое решение должно быть основано на командной строке).

решение1

Если вам нужно что-то более простое, чем решение AVFS, я написал скрипт на Python, который позволяет это сделать.arkfind. На самом деле вы можете просто сделать

$ arkfind /path/to/search/ -g "*vacation*jpg"

Это будет сделано рекурсивно, так что вы сможете просматривать архивы внутри архивов на произвольной глубине.

решение2

(Адаптирован изКак выполнить рекурсивный grep по сжатым архивам?)

УстановитьАВФС, файловая система, которая обеспечивает прозрачный доступ внутри архивов. Сначала выполните эту команду один раз, чтобы настроить вид файловой системы вашего компьютера, в котором вы можете получить доступ к архивам, как если бы они были каталогами:

mountavfs

После этого, если /path/to/archive.zipэто распознанный архив, то ~/.avfs/path/to/archive.zip#это каталог, который, по-видимому, содержит содержимое архива.

find ~/.avfs"$PWD" \( -name '*.7z' -o -name '*.zip' -o -name '*.tar.gz' -o -name '*.tgz' \) \
     -exec sh -c '
                  find "$0#" -name "*vacation*.jpg"
                 ' {} 'Test::Version' \;

Пояснения:

  • Смонтируйте файловую систему AVFS.
  • Найдите архивные файлы в ~/.avfs$PWD, что является представлением AVFS текущего каталога.
  • Для каждого архива выполнить указанный фрагмент оболочки (с $0= именем архива и $1= шаблоном для поиска).
  • $0#представляет собой каталог просмотра архива $0.
  • {\}а не {}требуется в случае, если внешние аргументы findзаменяют {}внутренние -exec ;(некоторые делают это, некоторые нет).

Или в zsh ≥4.3:

mountavfs
ls -l ~/.avfs$PWD/**/*.(7z|tgz|tar.gz|zip)(e\''
     reply=($REPLY\#/**/*vacation*.jpg(.N))
'\')

Пояснения:

  • ~/.avfs$PWD/**/*.(7z|tgz|tar.gz|zip)сопоставляет архивы в представлении AVFS текущего каталога и его подкаталогов.
  • PATTERN(e\''CODE'\')применяет КОД к каждому совпадению ОБРАЗЦА. Имя сопоставленного файла находится в $REPLY. Установка replyмассива превращает совпадение в список имен.
  • $REPLY\#представляет собой каталог просмотра архива.
  • $REPLY\#/**/*vacation*.jpgсоответствует *vacation*.jpgфайлам в архиве.
  • Квалификатор Nglob расширяет шаблон до пустого списка, если совпадений нет.

решение3

Другое работающее решение —zgrep

zgrep -r filename *.zip

решение4

Мойобычныйрешение:

find -iname '*.zip' -exec unzip -l {} \; 2>/dev/null | grep '\.zip\|DESIRED_FILE_TO_SEARCH'

Пример:

find -iname '*.zip' -exec unzip -l {} \; 2>/dev/null | grep '\.zip\|characterize.txt'

Результаты такие:

foozip1.zip:
foozip2.zip:
foozip3.zip:
    DESIRED_FILE_TO_SEARCH
foozip4.zip:
...

Если вам нужен только zip-файл схитыв теме:

find -iname '*.zip' -exec unzip -l {} \; 2>/dev/null | grep '\.zip\|FILENAME' | grep -B1 'FILENAME'

ИМЯ ФАЙЛАздесь используется дважды, поэтому можно использовать переменную.

С помощью find вы можете использоватьПУТЬ/К/ПОИСКУ

Связанный контент