в
zipgrep поиск во вложенных zip не распаковывая

о
команда zipgrep предназначена для поиска текста внутри одного zip-архива без его предварительной распаковки на диск. Однако стандартный zipgrep не умеет рекурсивно заглядывать во вложенные (дочерние) zip-архивы (например, archive.zip, внутри которого лежит sub.zip). [1, 2, 3, 4]

Для решения этой задачи не распаковывая архивы вручную, есть два основных пути: специализированная утилита ugrep (рекомендуется) или написание bash-скрипта. [1, 2]

Вариант 1: Использование ugrep (Самый удобный и мощный)

Современная утилита ugrep имеет встроенную поддержку поиска внутри архивов любых форматов (включая zip, tar, gz) и умеет автоматически сканировать вложенные архивы. [1, 2, 3]

Установите её (например, через sudo apt install ugrep в Ubuntu/Debian) и выполните команду: [1]

ugrep -z --zmax=3 -rn "find text" ваш_архив.zip

Ключи и параметры:

-z — активирует поиск внутри архивов и сжатых файлов.--zmax=3 — указывает глубину вложенности (насколько глубоко во вложенные архивы нужно заглядывать). Установите нужный уровень.-r — поиск во всех файлах внутри архива.-n — выводить номер строки, где найден текст. [1, 2, 3, 4]

Вариант 2: Bas скрипт (Для стандартных систем с unzip)

Если ugrep недоступен, можно автоматизировать процесс с помощью скрипта. Так как обычный unzip не может просматривать вложенные архивы на лету, скрипт будет временно извлекать их в оперативную память (RAM) или использовать python для обработки дерева без сохранения на жесткий диск. [1]

Простой пример скрипта для поиска текста во всех уровнях вложенности внутри текущей директории:

find . -name "*.zip" -exec sh -c '
  python3 -c "
import zipfile, io, sys

def search_zip(file_path, search_term, parent_name=\"\"):
    try:
        with zipfile.ZipFile(file_path, \"r\") as zf:
            for name in zf.namelist():
                # Если нашли еще один zip-архив
                if name.lower().endswith(\".zip\"):
                    nested_data = zf.read(name)
                    search_zip(io.BytesIO(nested_data), search_term, f\"{parent_name}/{name}\")
                else:
                    try:
                        content = zf.read(name).decode(\"utf-8\", \"ignore\")
                        if search_term in content:
                            print(f\"Найдено в {parent_name}/{name}\")
                    except:
                        pass
    except Exception as e:
        pass

search_zip(\"{}\", \"искомый_текст\", \"{}\")
"
' \;

Альтернатива: Смонтировать архив через AVFS

В Linux-системах можно прозрачно «смонтировать» файловую систему архивов с помощью FUSE-модуля AVFS. После монтирования любой zip-архив будет виден как обычная папка. [1, 2]

После установки и запуска службы вы сможете использовать обычный grep -r, а система сама будет распаковывать их на лету в фоновом режиме:

avfsd ~/.avfs
grep -r "искомый_текст" ~/.avfs/полный/путь/к/вашему/архиву.zip/
