1

Здравствуйте! Необходимо осуществить поиск pattern'a в файле любого формата. В качестве pattern'a может выступать какая-либо последовательность байт. Как это можно сделать при использовании Python?

insolor
  • 49,104
kmz_61
  • 251
  • Если дополнительных ограничений нет, то pattern in s, где s это mmap, скажет есть ли pattern в файле. s.find(pattern) возвращает позицию pattern в файле (смещение в байтах). Вот пример кода с mmap (в конце ответа)—выбор случайных слов из файла. – jfs Dec 22 '16 at 18:49
  • Есть еще одно ограничение - размер файла, который может быть несколько Гб – kmz_61 Dec 23 '16 at 08:44
  • Решение с mmap работает и для многострочного pattern, для pattern размером от одного байта до всех байт в файле и для больших файлов, которые в памяти не помещаются. – jfs Dec 23 '16 at 08:45
  • import mmap

    def searchPattern(filename): with open(filename, 'r+b') as file: map = mmap.mmap(file.fileno(), 0)

    def main(): searchPattern('C:\Temp\src\squid.log')

    if name == 'main': main()

    – kmz_61 Dec 23 '16 at 08:46
  • WindowsError: [Error 8] – kmz_61 Dec 23 '16 at 08:48

1 Answers1

4

Чтобы узнать содержит ли файл возможно многострочный pattern размеров от одного байта до всех байт в файле:

#!/urs/bin/env python2
"""Usage: find-pattern <pattern> <filename>"""
import mmap
import sys
from contextlib import closing

pattern, filename = sys.argv[1:]
with open(filename, 'rb', 0) as file, \
     closing(mmap.mmap(file.fileno(), 0, access=mmap.ACCESS_READ)) as s:
    sys.exit(s.find(pattern) == -1)

Скрипт возвращает ноль, если найден pattern и 1 иначе. mmap поддерживает и файлы больше доступной памяти.

Если размер файла больше адресного пространства (на 32-битной системе может встретиться), то можно mmap по частям делать и проверять len(pattern) части на границе кусков руками. В этом случае, возможно вариант с file.read(chunksize) удобней напрямую использовать без mmap.

jfs
  • 52,361