(Адаптировано из Как рекурсивно grep через сжатые архивы? )
Установите AVFS , файловую систему, которая обеспечивает прозрачный доступ внутри архивов. Сначала выполните эту команду один раз, чтобы настроить вид файловой системы вашего компьютера, в которой вы можете получить доступ к архивам, как если бы они были каталогами:
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'\')
применяет код для каждого совпадения PATTERN. Имя соответствующего файла находится в $REPLY
. Установка reply
массива превращает совпадение в список имен.
$REPLY\#
это каталог просмотра архива.
$REPLY\#/**/*vacation*.jpg
сопоставляет *vacation*.jpg
файлы в архиве.
- Спецификатор
N
glob расширяет шаблон до пустого списка, если совпадений нет.
Жиль "ТАК - прекрати быть злым"
источник
Мое обычное решение:
Пример:
Resuls похожи на:
Если вы хотите только zip-файл с попаданиями :
FILENAME здесь используется дважды, поэтому вы можете использовать переменную.
С помощью find вы можете использовать PATH / TO / SEARCH
источник
Другое решение, которое работает
zgrep
источник
zgrep
? Это не работает с тем, что поставляется с GNUgzip
(/bin/zgrep: -r: option not supported
,zgrep (gzip) 1.6
)ИМХО удобство работы также должно быть в bash:
и для гудрона (этот не проверен ...)
источник
unzip
реализация может работать с файлами 7z или tar.gz?libarchive
«sbsdtar
может обрабатывать большинство из этих форматов файлов, так что вы можете сделать:Что вы можете упростить (и улучшить, чтобы сопоставить без учета регистра) с GNU
find
:Это не печатает путь архива, где эти
*vacation*jpg
файлы найдены все же. Чтобы напечатать это имя, вы можете заменить последнюю строку на:который дает вывод как:
Или с
zsh
:Обратите внимание, что есть ряд других форматов файлов, которые являются просто
zip
илиtgz
замаскированными файлами типа.jar
или.docx
файлами. Вы можете добавить их в свой шаблонfind
/zsh
search,bsdtar
не заботясь о расширении (например, он не использует расширение для определения типа файла).Обратите внимание, что
*vacation*.jpg
приведенное выше сопоставляется с полным путем к элементу архива, а не только с именем файла, поэтому он будет совпадать с включенным,vacation.jpg
но также и с включеннымvacation/2014/file.jpg
.Чтобы сопоставить только имя файла, можно использовать режим извлечения , использовать
-s
(замену), который использует регулярные выражения сp
флагом для печати имен соответствующих файлов, а затем убедиться, что ни один файл не извлечен, например:Обратите внимание, что он выведет список на stderr и добавит
>>
к каждой строке. В любом случае,bsdtar
как и в большинствеtar
реализаций, могут отображаться имена файлов на дисплее, если они содержат некоторые символы, такие как символ новой строки или обратный слеш (отображается как\n
или\\
).источник