2012-04-11 106 views
0

我是一个蟒蛇新手,我在这里挣扎着一些概念 - 任何帮助表示赞赏。使用Python2.6来解析Bash输出

我有一个自定义的系统工具,查询数据库,并返回几行的结果看的 - 每行一个。以下python脚本接受来自raw_input的站点FQDN并在该fqdn上运行$ path。

#!/usr/bin/python 

import subprocess 
import getpass 

#get the site name. 
site = raw_input("What is the name of the site?: ").strip() 

#run path. 
cmd = 'path '+ site; 
p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE); 
path_output = p.stdout.read().strip().split('\n') 

print path_output 

它返回这样的这样的结果:

[' fqdn   = www.hcasc.info', ' account_id = 525925', ' parent_id  = 525925', ' nfs   = /mnt/stor7-wc2-dfw1/525925/www.hcasc.info', ' server_type = PHP5', ' ssl   = False', ' host_ip  = 98.129.229.186', ' cgi_hosting = False', ' test_link_ip = 98.129.229.186', ' ipv6_ip  = 2001:4800:7b02:100::1600:0'] 

我怎样才能从“NFS =等”额外的空格出来,或只采取第三列(又名的awk“{打印$ 3 }')和/或从bash中分配这些结果的每一部分来分离变量以便进一步操作?

只是遇到了一些麻烦安装这个学习曲线,你的帮助是真诚的赞赏。

回答

1

第三列将是line.split()[2];如果你想扔掉前两个单词,并采取其余的,它是line.split(None, 2)[-1]。 (split不带参数,或None作为第一个参数,分割上任何空白。)

>>> ' fqdn   = www.hcasc.info'.split() 
['fqdn', '=', 'www.hcasc.info'] 

>>> for var, equals, rest in (l.split(None, 2) for l in path_output): 
    assert equals == '=' 
    print var, 'is', rest 

fqdn is www.hcasc.info 
account_id is 525925 
parent_id is 525925 
nfs is /mnt/stor7-wc2-dfw1/525925/www.hcasc.info 
server_type is PHP5 
ssl is False 
host_ip is 98.129.229.186 
cgi_hosting is False 
test_link_ip is 98.129.229.186 
ipv6_ip is 2001:4800:7b02:100::1600:0 

说明: (l.split(None, 2) for l in path_output)发生器表达,它运行l.split(None, 2)path_output每个值(称它为l)。这就像一个列表的理解,这是同样的事情,但[]围绕它,而不是(),但随着for循环越过它,然后忘记以前的值它只运行l.split通话,而列表理解将构建一个大名单在每个步骤中首先执行l.split的所有结果,然后正常循环该列表。这种方式就像做

for line in path_output: 
    var, equals, rest = line.split(None, 2) 
    ... 

但有点短。 :)


如果你想把这变成一本字典,为DSM suggests,你可以用这种方式(仅适用于上下文)这样做,因为

d = dict((var, rest) for var, equals, rest in (l.split(None, 2) for l in path_output)) 

,或者在Python 2.7/3,该好得多

d = { var: rest for var, equals, rest in (l.split(None, 2) for l in path_output) } 

当然,你可以把这个有点更具可读性两行:

output_vals = (l.split(None, 2) for l in path_output) 
d = dict((var, rest) for var, equals, rest in output_vals) 

无论您想要一本字典,或只是一个循环取决于你打算用它做什么样的处理,但字典可能是对大多数事情的更好方法。

0

第二个问题,第一:你可以收集在一个列表中的结果,但它是更加便利使用字典。

第一个问题:既然你的结果是所有形式key = value,你可以这样提取出来:

results = dict() 
for line in p.stdout: 
    key, value = line.split('=') 
    results[key.strip()] = value.strip() 

当调用p.stdout(或任何文本文件的对象)这样的,它隐含在读取一行一次。下一个语句将等号上的行分开,并将这些部分分配给两个变量。最后,我们将keyvalue左右的空格分开并将它们存储在字典中。

PS。你也可以用空格分割这一行,用line.split();但如果值或(不太可能)密钥包含嵌入空间,则会出现问题。