我有以下代码:
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
文件获取结果作为差异,实际上我想知道{4}中的内容{1}}并且不在pip.csv
中。 here中的示例并不适用于我的情况,但我会通过列出名称和版本以类似的方式输出结果。
编辑: @Greg Sadetsky感谢您使用您的示例来简化我的代码的建议,但没有解决我的问题,我无法通过这种方式比较列表。我取得了一些进展,但我还没有得到所需的输出:
pacman.csv
当我运行此代码时,我会收到一些大写字母,例如:Imgur
好的,所以看完套装之后我就这样做了:
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)
但是我得到了类似的结果,只出现了大写字母中的第一个字母。
答案 0 :(得分: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
编辑:
1-为什么要经历编写CSV文件然后再读回来然后只比较这些集合的麻烦?为什么不简单地检查sys_apps
和pip_apps
之间的区别?我想你需要写入CSV文件,你需要从这些文件中读回来然后比较它们的内容。
2-我看到你正在混合Python 2和Python 3代码(你有一个“sep”参数要拆分,但你也在字符串上调用“decode”)。您使用的是哪个版本的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
的所有包的列表。
请告诉我这是否有帮助!