2013-04-29 3 views
1

У меня есть два текстовых файла, которые я хочу сравнить с помощью Python. Оба этих файла имеют дату в заголовке. Таким образом, я хочу игнорировать эту строку при сравнении, поскольку она всегда будет меняться и не должна рассматриваться как разница.Игнорирование строк при сравнении файлов с использованием Python

File1

Date : 04/29/2013 
Some Text 
More Text 
.... 

File2

Date : 04/28/2013 
Some Text 
More Text 
.... 

Я попытался их сравнения с помощью filecmp модуля, но не поддерживает каких-либо аргументов, чтобы игнорировать любой узор. Есть ли другой модуль, который можно использовать для этой цели. Я пробовал использовать difflib, но не был успешным. Более того, я просто хочу, есть ли различия в черно-белых файлах, так как True or False, difflib печатал все строки, даже если не было разницы using whitespace.

ответ

4

Использование itertools.ifilter (или в Python 3 раз нормально filter)

itertools.ifilter(predicate, iterable)

Ваш предикат должен быть функцией, возвращаясь False для строк, которые вы хотите игнорировать. например.

def predicate(line): 
    if 'something' in line: 
     return False # ignore it 
    return True 

Затем используйте его на своем файловом объекте. fin = ifilter(predicate, fin)

Тогда просто использовать что-то вроде

from itertools import izip, ifilter # on Py3 instead use normal zip and filter 
f1 = ifilter(predicate, f1) 
f2 = ifilter(predicate, f2) 

all(x == y for x, y in izip(f1, f2)) 

Вам не нужно difflib, если вы не хотите видеть, что различия были, и так как вы пытались filcmp я предполагаю, что вы только хотите, чтобы узнать, были ли разница или нет. К сожалению, filecmp работает только с именами файлов.

Также для пропуска первой строки каждого файла использовать только itertools.islice(fin, 1, None)

from itertools import islice, izip 

def predicate(line): 
    ''' you can add other general checks in here ''' 
    if line.startswith('Date'): 
     return False # ignore it 
    return True 

with open('File1.txt') as f1, open('File2.txt') as f2: 
    f1 = ifilter(predicate, f1) 
    f2 = ifilter(predicate, f2) 
    print(all(x == y for x, y in izip(f1, f2))) 

>>> True 
+0

Я пробовал это, но я получаю ошибку. Не могли бы вы поправить меня, если я что-то не так '>>> fo1 = open (" file1.txt "," r ") >>> fo2 = open (" file2.txt "," r ") >>> f1 = ifilter (« Дата », fo1) >>> f2 = ifilter (« Дата », fo2) >>> all (x == y для x, y в izip (f1, f2)) Traceback (самый последний вызов последнего): Файл "", строка 1, в Файл "", строка 1, в TypeError: 'ул' объект не callable' – sarbjit

+0

@sarbjit 'предикат' должен быть функцией, я обновил свой ответ, чтобы показать пример. – jamylak

+0

Отлично !! Спасибо за вашу помощь – sarbjit

0

Если вы знаете, что эта дата всегда на первой линии и копировать строки в списке строк вы можете просто удалить первую строку, написав строки [1:]

Добавлено после комментария:

Возможно, лучше использовать ifilter в другом решении. Если файлы отличаются друг от друга, вам необходимо пройти через них (используя два индекса, по одному для каждого файла) и пропустить строки, содержащие одно из ключевых слов.

+4

Не идеально, если большой ... использовать itertools.islice (СПЧ, 1, None) и выполнить пошаговый - более общий и сохраняет память –

+0

Ну, в большинстве файлов дата будет отличаться и обычно находится на первой линии. Но у некоторых моих файлов есть другие ключевые слова, которые будут меняться и могут быть в любом месте файла. Итак, я ищу более общее решение, которое будет работать для каждого случая. – sarbjit

Смежные вопросы