Почему '\ x01 \ x1A' (управляющие символы начала заголовка и замены) в строке текстового файла преждевременно останавливают цикл for? - PullRequest
0 голосов
/ 02 ноября 2018

Я использую Python 2.7.15, Windows 7

Context

Я написал скрипт для чтения и токенизации каждой строки файла журнала FileZilla (спецификации здесь ) для IP-адреса хоста, который инициировал соединение с сервером FileZilla. У меня проблемы с анализом поля log text, следующего за символом >. Скрипт, который я написал, использует:

    with open('fz.log','r') as rh:
       for lineno, line in rh: 
          pass

конструкция для чтения каждой строки. Этот цикл for преждевременно остановился, когда обнаружил поле log text, содержащее символы SOH и SUB. Я не могу показать вам файл журнала, поскольку он содержит конфиденциальную информацию, но суть проблемы можно воспроизвести, прочитав текстовый файл, содержащий эти символы в строке.

Моя цель - извлечь IP-адреса (что я могу сделать, используя re.search()), но прежде чем это произойдет, я должен удалить эти управляющие символы. Я делаю это, создавая копию файла журнала, где удаляются строки, содержащие эти управляющие символы. Возможно, есть лучший способ, но мне более любопытно, почему цикл for просто останавливается после встречи с управляющими символами.

Воспроизведение номера

Я воспроизвел проблему с этим кодом:

if __name__ == '__main__':
    fn = 'writetest.txt'
    fn2 = 'writetest_NoControlChars.txt'

    # Create the problematic textfile
    with open(fn, 'w') as wh: 
        wh.write("This line comes first!\n");
        wh.write("Blah\x01\x1A\n"); # Write Start-of-Header and Subsitute unicode character to line
        wh.write("This comes after!")

    # Try to read the file above, removing the SOH/SUB characters if encountered
    with open(fn, 'r') as rh:
        with open(fn2, 'w') as wh:
            for lineno, line in enumerate(rh):
                sline = line.translate(None,'\x01\x1A')
                wh.write(sline)
                print "Line #{}: {}".format(lineno, sline)
    print "Program executed."

выход

Приведенный выше код создает 2 выходных файла и создает в окне консоли следующее:

Line #0: This line comes first!

Line #1: Blah
Program executed.

Я пошагово отлаживал код в Eclipse и сразу после выполнения

for lineno, line in enumerate(rh): 

, rh, дескриптор этого открытого файла был закрыт. Я ожидал, что он переместится на третью строку, напечатав This comes after! для консоли и записав его в writetest_NoControlChars.txt, но ни одно из событий не произошло. Вместо этого исполнение прыгнуло до print "Program executed". Изображение значений локальной переменной в консоли отладки

1 Ответ

0 голосов
/ 02 ноября 2018

Вам нужно открыть этот файл в двоичном режиме, если вы знаете, что он содержит нетекстовые данные: open(fn, 'rb')

...