0

我是 python 新手,在这里遇到了一些概念 - 任何帮助表示赞赏。

我有一个自定义系统工具,可以查询数据库,并返回几行作为要读取的结果——每行一个。以下 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 = etc”中取出多余的空格,或者只取第三列(又名 awk '{print $3}')和/或将 bash 中的每一个结果分配给单独的变量以进行进一步操作?

只是在安装此学习曲线时遇到了一些麻烦,我们真诚地感谢您的帮助。

4

2 回答 2

1

第三列是line.split()[2]; 如果你想扔掉前两个词并取其余词,那就是line.split(None, 2)[-1]. (split没有参数,或 aNone作为第一个参数,在任何空白处拆分。)

>>> '    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_outputl[]()l.splitforl.split

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

但短一点。:)


如果您想将其放入字典中,如DSM 建议的那样,您可以以这种方式(仅用于上下文)作为

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)

您是否需要字典或只是循环取决于您将对其进行的处理,但字典可能是大多数事情的更好方法。

于 2012-04-11T03:10:38.880 回答
0

首先第二个问题:您可以将结果收集在一个列表中,但使用字典更方便。

第一个问题:由于您的结果都在 formkey = value中,您可以像这样提取它们:

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

当像这样调用p.stdout(或任何文本文件对象)时,它一次隐式读取一行。下一条语句在等号上拆分行,并将各部分分配给两个变量。最后,我们去除周围的空白key并将value它们存储在字典中。

PS。line.split()您还可以使用;在空白处拆分行 但是如果值或(不太可能)键包含嵌入空间,那么您就会遇到问题。

于 2012-04-11T20:50:26.600 回答