2016-03-06 4 views
0

У меня есть следующий код:Как сравнить два файла CSV в Python 3 - формат модулей -

import csv 
import subprocess 

from subprocess import check_output 

# Writing the pacman command output to file in csv format 

sysApps = check_output(["pacman", "-Qn"]) 
sysAppsCSV = csv.DictReader(sysApps.decode('ascii').splitlines(), 
         delimiter=' ', skipinitialspace=True, 
         fieldnames=[ 'name', 'version']) # Thanks to https://stackoverflow.com/a/8880768/5565713 jcollado 

with open('pacman.csv', 'w') as csvfile: 
    rows_sys = csv.writer(csvfile) 
    rows_sys.writerow(sysAppsCSV) 

# Writing the pip command output in csv format 

pipApps = check_output(["pip", "list"]) 
pipAppsCSV = csv.DictReader(pipApps.decode('ascii').splitlines(), 
         delimiter=' ', skipinitialspace=True, 
         fieldnames=[ 'name', 'version']) # Thanks to https://stackoverflow.com/a/8880768/5565713 jcollado 

with open('pip.csv', 'w') as csvfile: 
    rows_pip = csv.writer(csvfile) 
    rows_pip.writerow(pipAppsCSV) 

# Comparing the files 

Я хочу, чтобы сравнить два файла, не нужно файлы, которые он также может быть содержание переменных уже создан, и получить результат как отличается от pip.csv файл, практически я хочу знать, что есть в pip.csv и не находится в pacman.csv. Пример от here не относится к моей ситуации, но я приведу результат аналогичным образом, указав имя и версию.

EDIT: @Greg Sadetsky Спасибо за предложение. Я использовал ваш пример, чтобы упростить мой код, но не решает мою проблему, поэтому я не могу сравнивать списки таким образом. Я сделал некоторые успехи, но я до сих пор не получаю желаемый результат:

import csv 
import subprocess 

from subprocess import check_output 

#Initializing variables 

results_sys = "" 
results_pip = "" 

# Running the linux commands 

sys_apps = set(check_output(["pacman", "-Qn"]).splitlines()) 
pip_apps = set(check_output(["pip", "list"]).splitlines()) 

# Saving the outputs of the commands in to a CSV format 

for row in sys_apps: 
    result = row.decode('ascii').split(sep=" ") 
    with open('pacman.csv', 'a') as csvfile: 
     rows_sys = csv.writer(csvfile) 
     rows_sys.writerow(result) 

for row in pip_apps: 
    result = row.decode('ascii').split(sep=" ") 
    with open('pip.csv', 'a') as csvfile: 
     rows_sys = csv.writer(csvfile) 
     rows_sys.writerow(result) 

# Opening the files and comparing the results 

with open('pacman.csv', 'r') as pacmanCSV: 
    sys_apps = pacmanCSV.readlines() 
    for row in sys_apps: 
     apps = row.split(",") 
     results_sys = results_sys + " " + apps[0] 

with open('pip.csv', 'r') as pipCSV: 
    pip_apps = pipCSV.readlines() 
    for row in pip_apps: 
     apps = row.split(",") 
     results_pip = results_pip + " " + apps[0] 


results_final = "List of apps installed from pip:\n################################" 
for val in results_pip: 
    if val not in results_sys: 
     results_final = results_final + "\n" + val 


print(results_final) 

Когда я запускаю этот код я получаю некоторые заглавные буквы, например: Imgur

cropped version

ИТАК после чтение о наборе я сделал это:

r1 = set(results_pip) 
r2 = set(results_sys) 

print(r1 - r2) 

Но я получаю схожие результаты, появляются только первые буквы в шапках.

+0

http://stackoverflow.com/questions/15864641/python-difflib-comparing-files http://stackoverflow.com/questions/977491/comparing-2-txt-files-using-difflib-in-python – Sam

+0

Проблема заключается в том, что как 'results_sys', так и' results_pip' являются строками, к которым вы непрерывно добавляете биты строки (то есть 'results_sys +" "+ apps [0]'). Если вы перебираете строку так же, как и в 'for val в results_pip', вы будете перебирать буквы в этой строке один за другим ... это не то, что вы хотите сделать. Я отредактирую свой ответ с решением для вашей новой версии –

ответ

1

Вы можете сравнить два списка пакетов с помощью sets и легко выяснить, какие пакеты находятся в одном списке и отсутствуют другие.

Вам абсолютно необходимо проходить через CSV-файлы? Вы просто ищете разницу между pacmac и pip? Если это так, я создал более простой пример ниже.

Примечание: У меня на моей машине нет pacman, но я полагаю, что его выходной формат аналогичен pip. Если нет, вам придется настроить код.

from subprocess import check_output 

sys_apps = set(check_output(["pacman", "-Qn"]).splitlines()) 
pip_apps = set(check_output(["pip", "list"]).splitlines()) 

# show packages present in sys_apps that are absent from pip_apps 
print sys_apps - pip_apps 

EDIT:

1- Почему пройти через трудности для записи в файл CSV, а затем читать их обратно, а затем только сравнивая наборы? Почему бы просто не проверить разницу между sys_apps и pip_apps? Я полагаю, что вам нужно писать в CSV-файлы и что вам нужно прочитать данные из этих файлов, а затем сравнить их содержимое.

2- Я вижу, что вы смешиваете код Python 2 и Python 3 (у вас есть аргумент «sep» для разделения, но вы также вызываете «декодировать» строку). Какую версию Python вы используете?

3- Я вижу, что вы немного изменили свой код. Как я объяснил в своем комментарии к вашему вопросу, выполнив for val in results_pip, вы повторяете символы этой строки, что, вероятно, не то, что вы хотите сделать (вы, вероятно, хотели перебирать элементы списка).

Я только вывесить другой вариант нижней части кода:

# Opening the files and comparing the results 

with open('pacman.csv', 'r') as pacmanCSV: 
    sys_apps = pacmanCSV.readlines() 

with open('pip.csv', 'r') as pipCSV: 
    pip_apps = pipCSV.readlines() 

print "List of apps installed from pip:\n################################" 

print set(pip_apps) - set(sys_apps) 

Как вы видите, я не разделив строки из файлов CSV на запятые, так как вы можете сравнить полный имена пакетов, включая версии (я думаю, было бы важно проверить, есть ли у вас разные версии пакетов, установленных через pip). Если вы абсолютно хотите сравнить имена пакетов (не на версии), вы можете изменить два with блока к следующему:

with open('pacman.csv', 'r') as pacmanCSV: 
    sys_apps = [app.split(',')[0] for app in pacmanCSV.readlines()] 

with open('pip.csv', 'r') as pipCSV: 
    pip_apps = [app.split(',')[0] for app in pipCSV.readlines()] 

это извлекает имя пакета, используя раскол, а затем сохраняет только имя пакета, и строит список всех пакетов, которые становятся sys_apps ans pip_apps.

Дайте мне знать, если это поможет!

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