解析命令行输出并使用Python将结果存储在字典中

时间:2017-04-18 22:57:16

标签: python python-2.7 dictionary

我正在使用子进程执行命令,然后尝试解析其输出。输出的类型为:

obj 6
endobj 6
第12页 ...... ...

此输出将在一堆文件中生成。

结果应该是这样的:

[OBJ; 6,8,3,....对于所有文件]
[endobj; 6,4,5,.....适用于所有文件]
...
...

我设法创建了以下程序:

import subprocess
import os
import re
from collections import defaultdict

def run_pdfid(filename, d):
    try:
        p = subprocess.Popen(['python',
                            '/Users/as/Desktop/tools/pdfid_v0_2_1/pdfid.py',filename],stdout=subprocess.PIPE)

        for line in p.stdout:
            if '%PDF' in line or line.startswith('PDFiD'):
                continue
            pattern1 = "^\s*(\S+)\s+(\d+)"
            m = re.search(pattern1, line)
            key = m.group(1)
            if key in d:
                d[key].append(m.group(2))
            else:
                d[key] = m.group(2)
    except Exception:
        match = None



if __name__ == '__main__':
    os.chdir('/Users/as/Desktop/shared/clean')
    d = dict()
    for root, dirs, file_names in os.walk(os.getcwd()):
        for file in file_names:
            #print file
            run_pdfid(file, d)

    for key, value in d.iteritems():
        print (key, value)

除了字典创建外,一切似乎都运行正常。能帮我看看这个问题吗?

编辑:正如所建议的那样,我将字典创建移出了循环,它似乎对我有所帮助。我得到的当前输出只是每个键记录一个值。我希望它将包含所有文件的值。 当前输出如下:

(' obj',' 8')
(' / JS',' 2')
(' stream',' 1')
(' endobj',' 8')

应该是: (' obj',' 8',' 6',' 5',.....)
...
...

1 个答案:

答案 0 :(得分:0)

您继续重新创建字典,但之后您只使用最终字典。您应该更多地缩进最后两行,或者将字典创建移出循环,具体取决于您是希望所有文件都在同一个字典中,还是想要在所有文件上报告一次。

正如您所说,如果您想要所有文件的单个报告,则需要在循环之前将字典创建(d = dict())向上移动。

已编辑添加:

重新评论,您可能只需添加一次密钥,然后在尝试追加时触及异常。您可以将d[key].append(m.group(2))更改为d[key].append([m.group(2)]),但实际上defaultdict的全部目的是不必具有if / else逻辑,因此我只需替换:

if key in d:
   d[key].append(m.group(2))
else:
   d[key] = m.group(2)

使用:

d[key].append(m.group(2))

使用defaultdict时,没有理由检查密钥是否已存在。