2016-10-06 4 views
4

Прежде всего, я искал в Интернете и stackoverflow около 3 дней и не нашел ничего, что искал.Получить разницу между двумя файлами

Я делаю еженедельный аудит безопасности, когда я возвращаю CSV-файл с IP-адресами и открытыми портами. Они выглядят так:

20160929.csv

10.4.0.23;22 
10.12.7.8;23 
10.18.3.192;23 

20161006.csv

10.4.0.23;22 
10.18.3.192;23 
10.24.0.2;22 
10.75.1.0;23 

Разница заключается в том: 10.12.7.8:23 был закрыт. 10.24.0.2:22 и 10.75.1.0:23 открыт.

Я хочу, чтобы скрипт, который выводит меня:

[-] 10.12.7.8:23 
[+] 10.24.0.2:22 
[+] 10.75.1.0:23 

Как я могу сделать сценарий, как это? Я пробовал свой difflib, но это не то, что мне нужно. Мне нужно также написать это позже или отправить этот вывод в виде почты, для которой у меня уже есть скрипт.

Я не могу использовать Unix, потому что в нашей компании мы имеем среду Windows и не можем использовать другую ОС. Поэтому я не могу использовать diff или некоторые другие отличные инструменты.

Это моя первая попытка:

old = set((line.strip() for line in open('1.txt', 'r+'))) 
new = open('2.txt', 'r+') 
diff = open('diff.txt', 'w') 

for line in new: 
    if line.strip() not in old: 
     diff.write(line) 
new.close() 
diff.close() 

Это моя вторая попытка

old = set((line.strip() for line in open('1.txt', 'r+'))) 
new = open('2.txt', 'r+') 
diff = open('diff.txt', 'w') 

for line in new: 
    if line.strip() not in old: 
     diff.write(line) 
new.close() 
diff.close() 
+0

Если строки могут быть в любом порядке, создание наборов для каждого файла будет вариантом. Что вы уже пробовали? – Caramiriel

+0

@Caramiriel Это оба: https://paste.ee/p/7KNxv и https://paste.ee/p/kPOle Надеюсь, что paste.ee в порядке. –

+0

@ e4c5 Я знаю, я относительно новичок в написании сценариев с питоном, и я разместил эти два источника выше. Для всего, что я нахожу объяснение, а затем я использую это, чтобы закодировать его по-своему. Но я ничего не нашел по этому поводу. - Я узнал, как я могу получить результат, если есть какая-то разница между одной строкой в ​​обоих файлах, но не если они являются случайным порядком, как в моем примере. –

ответ

1

Использование кода в качестве базы, вы можете сделать следующее:

old = set((line.strip() for line in open('1.txt'))) 
new = set((line.strip() for line in open('2.txt'))) 

with open('diff.txt', 'w') as diff: 
    for line in new: 
     if line not in old: 
      diff.write('[-] {}\n'.format(line)) 

    for line in old: 
     if line not in new: 
      diff.write('[+] {}\n'.format(line)) 

Там в несколько ухищрений здесь:

  1. Мы хотим прочитать отдельные строки как старого, так и нового файлов для сравнения.
  2. Нам не обязательно strip каждой отдельной строкой, как мы это сделали, читая файл.
  3. Мы используем {} и .format() для создания текстовых строк.
  4. Использование \n гарантирует, что мы поместим каждую запись в новую строку нашего выходного файла.
  5. Использование файла with для файла, который мы пишем, позволяет нам открывать его без необходимости звонить close и (если мои знания верны) позволяет лучше справляться с любыми сбоями программы после того, как файл был открыт.
+0

Ярлык может быть 'new.difference (old)' и наоборот, но это полностью необязательно – Caramiriel

+0

@asongtoruin Это именно то, что мне нужно. Спасибо! Этот момент, когда вы видите решение. - Я узнал, вам нужно только прочитать файл, чтобы я мог просто написать 'open ('1.txt')' или вы делаете это по какой-то причине? –

+0

@JoshE. 'open ('1.txt')' работает здесь, потому что режим 'open' по умолчанию« только для чтения », но (по крайней мере лично), я думаю, что он делает более читаемый код, если вы укажете, как вы открываете файл. – asongtoruin

0

Вы можете попробовать это одно:

old_f = open('1.txt') 
new_f = open('2.txt') 
diff = open('diff.txt', 'w') 

old = [line.strip() for line in old_f] 
new = [line.strip() for line in new_f] 

for line in old: 
    if line not in new: 
     print '[-] ' + str(line) 
     diff.write('[-] ' + str(line) + '\n' 


for line in new: 
    if line not in old: 
     print '[+]' + str(line) 
     diff.write('[+] ' + str(line) + '\n' 

old_f.close() 
new_f.close() 
diff.close() 
3

В следующем решении я использовал наборы, так что порядок не имеет значения, и мы можем сделать прямое вычитание со старым и новым, чтобы увидеть, что изменилось.

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

def read_items(filename): 
    with open(filename) as fh: 
     return {line.strip() for line in fh} 

def diff_string(old, new): 
    return "\n".join(
     ['[-] %s' % gone for gone in old - new] + 
     ['[+] %s' % added for added in new - old] 
    ) 

with open('diff.txt', 'w') as fh: 
    fh.write(diff_string(read_items('1.txt'), read_items('2.txt'))) 

Очевидно, что вы можете распечатать строку diff, если хотите.

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