Поиск строки в нескольких файлах zip


22

Я работаю над SunOS 5.10. У меня есть папка, которая содержит около 200 ZIP-файлов. Каждый почтовый файл содержит только один текстовый файл. Я хотел бы найти конкретную строку во всех текстовых файлах во всех файлах zip.

Я попробовал это (который ищет любой текстовый файл в zip-файле, который содержит строку «ORA-»), но это не сработало.

zipgrep ORA-1680 *.zip

Как правильно делать это, не распаковывая zip-файлы?


См. Также Как рекурсивно выполнять поиск в сжатых архивах? (не точный дубликат, потому что требования там были более сложными).
Жиль "ТАК - перестань быть злым"

Ответы:


26

Как правило, поиск содержимого в сжатом файле невозможен без его разархивирования. Так как zipgrep - это всего лишь оболочка, которая включает в себя разархивирование и сам egrep, вы можете сделать это вручную:

for file in *.zip; do unzip -c "$file" | grep "ORA-1680"; done

Если вам нужен только список подходящих zip-файлов, вы можете использовать что-то вроде:

for file in *.zip; do
    if ( unzip -c "$file" | grep -q "ORA-1680"); then
        echo "$file"
    fi
done

Таким образом, вы распаковываете только в стандартный вывод (т.е. в память), а не распаковываете файлы на диск. Конечно, вы можете попытаться использовать только grep -azip-файлы, но в зависимости от содержимого файла и вашего шаблона вы можете получить ложные срабатывания и / или ложные отрицания.


Куда первый вариант разархивирует файлы?
Зигги

2
unzip -cраспаковывает файл в стандартный вывод. Он не записывает весь несжатый файл в другом месте.
Ноя

+1 ткс много это спасет мой день. Я просто добавлю echo "$ file"; распаковать -c "$ file" | grep -q "ORA-1680"; знать имя файла + результат.
Майк

2
Моя версия unzipиспользует -pдля потоковой передачи на канал!
gavenkoa

Это работает, когда все однострочные команды возвращают «стандартный вывод», а не имя файла +1
alimack

16

zipgrepзанимает один файл. Чтобы заставить его работать с несколькими файлами, поместите его в цикл:

for i in *.zip
do
   zipgrep ORA-1680 "$i"
done

2
В одной строке выведите также zip-имя файла, если есть совпадение:for i in *.zip; do zipgrep TextToSearch $i && echo $i; done
baptx

4

В АВФ файловая система представляет собой вид файловой системы , где каждый архивный файл /path/to/foo.zipдоступен как каталог ~/.avfs/path/to/foo.zip#. Это файловая система FUSE , которую вы можете установить на Solaris. AVFS обеспечивает доступ только для чтения к большинству распространенных форматов архивных файлов.

mountavfs
for z in ~/.avfs$PWD/*.zip; do
  find "$z#" -exec grep ORA-1680 {} +
done
fusermount -u ~/.avfs   # optional
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.