Python — нужна помощь с разбором файла. Есть ли способ игнорировать символы EOF?

У меня есть двоичный файл, из которого я пытаюсь извлечь строки, и у меня достаточно времени для этого. :(

Моя текущая стратегия заключается в чтении файла с помощью Python (используя одну из следующих функций: read(), readline() или readlines()). Затем я анализирую строку (символ за символом) и ищу специальный символ 'ô', который в большинстве случаев непосредственно следует за нужными мне строками! Наконец, я анализирую в обратном порядке специальный символ, записывая все символы, которые я идентифицировал как «действительные».

В конце дня мне нужна передняя отметка времени и следующие 3 строки в строке.

Полученные результаты:

Во входной строке примера № 1 функции «чтения» не будут читать всю строку (показано на выходном изображении). Я считаю, что это связано с тем, что функция интерпретирует двоичный файл как символ EOF, а затем перестает читать.

В строке № 2 примера есть моменты, когда появляется «специальный символ», однако это не после строки, которую я хочу извлечь. :(

Есть ли лучший способ проанализировать эти данные? Если нет, есть ли способ решить проблему, показанную в строке примера № 1?

Примеры входных данных и результирующих выходных данных, когда я просто печатаю строки как прочитанные. Как видите, при использовании readlines() Примеры входных данных и результирующих выходных данных, когда я просто печатаю строки как прочитанные. Как видите, он не считывает всю строку, когда  используя readlines()

Мой алгоритм извлечения строк, который не очень надежен. Мой алгоритм извлечения строк, который не очень надежен.

К вашему сведению, эффективность не обязательно важна.


person jindurhur    schedule 03.05.2016    source источник
comment
Размещая свой код в виде снимка экрана, вы значительно усложняете нам задачу помочь вам.   -  person John Gordon    schedule 03.05.2016
comment
Нет такой вещи, как символ EOF, EOF — это просто условие достижения конца файла.   -  person Barmar    schedule 03.05.2016


Ответы (2)


Зачем использовать Python. Используйте струны и пропустите их через голову, например

    strings /bin/ls | head -3

и посмотреть, что вы получите. Вы также можете получить строки для Windows.

person Jorgen    schedule 03.05.2016
comment
Кажется, это то, что я ищу. Я скачал strings2 для Windows и попробовал, и, похоже, он работает хорошо! Вот вывод: ‹br/› 41080, 1-Hello Comapany Here ?= Carpenter 202-Carpenter House Personxyz <br/> 401058, owner of area LLC company names 213-Ingledue East names‹br/› ‹br/› Как вы можете, он ошибся только 1 раз. Я думаю, что это то, что я могу очистить в python, отфильтровав некоторые символы, которые, как я знаю, не будут использоваться. ‹br/› Спасибо за предложение @Jorgen. - person jindurhur; 04.05.2016
comment
Извините, я новичок в этом :/ Кажется, это то, что я ищу. Я скачал strings2 для Windows и попробовал, и, похоже, он работает хорошо! Вот результат: 41080, 1-Hello Comapany Here ?= Carpenter 202-Carpenter House Personxyz 401058, owner of area LLC company names 213-Ingledue East names Как вы можете, это только 1 раз испортилось. Я думаю, что это то, что я могу очистить в python, отфильтровав некоторые символы, которые, как я знаю, не будут использоваться. Спасибо за предложение @Jorgen. - person jindurhur; 04.05.2016

Если данные двоичные, не читайте их как текст. Прочитайте его как двоичные данные, а затем попытайтесь найти строки, встроенные в двоичные данные.

with open("example.tp", "b") as f:
    data = f.read() # produces a bytes object in python 3

Теперь разделите ваши данные на основе символа терминала

parts = data.split(b'\xf4') # f4 is hex code for your o character in latin-1

Теперь извлеките строку из каждой части как можно лучше:

from string import ascii_letters, digits

special_chars = '-()&, '
desired_chars = bytes(ascii_letters + digits + special_chars, encoding="ascii")

data = b'0,123\xf4NOPE#Hello world\xf4ignored' # sample data

parts = data.split(b'\xf4')

strings = []
for p in parts[:-1]: # ignore last part as it is never followed by the split char
    reversed_bytes = p[::-1]
    # extract the string
    for i, byte in enumerate(reversed_bytes):
        if byte not in desired_chars:
            chunk = reversed_bytes[:i]
            break
    else:
        chunk = reversed_bytes # all chars were valid
    bytes_ = chunk[::-1]
    bytes_ = bytes_.replace(b',', b'')
    strings.append(bytes_.decode("ascii")) # turn into a str
    # use ascii codec as there should be no non-ascii bytes in your string

print(strings) # prints ['0123', 'Hello world']
person Dunes    schedule 03.05.2016