0

私はPythonの初心者であり、ここでいくつかの概念に苦労しています-どんな助けでもありがたいです。

データベースにクエリを実行し、読み取る結果として複数の行を返すカスタムシステムツールがあります(各行に1つずつ)。次の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」から余分な空白を取り除くにはどうすればよいですか、または3番目の列(別名awk'{print $ 3}')を取得するか、bashからのこれらの結果の各部分をさらに操作するために別々の変数に割り当てるにはどうすればよいですか?

この学習曲線を実装するのに少し問題がありましたが、あなたの助けに心から感謝します。

4

2 に答える 2

1

3番目の列はline.split()[2];になります。最初の2つの単語を捨てて残りを取りたい場合は、ですline.split(None, 2)[-1]。(split引数なし、またはNone最初の引数としてaを使用すると、空白で分割されます。)

>>> '    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)の値ごとに実行されます。これはリスト内包に似ていますが、同じものですが、の代わりにその周りにありますが、ループが通過するときにのみ呼び出しを実行し、前の値を忘れますが、リスト内包はすべての結果を含む1つの大きなリストを作成します最初に各ステップで、次にそのリストを通常どおりループします。この方法は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) }

もちろん、これを2行でもう少し読みやすくすることもできます。

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

最初の2番目の質問:結果をリストに収集することもできますが、辞書を使用する方が便利です。

最初の質問:結果はすべて次の形式であるため、次のkey = valueように抽出できます。

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

p.stdoutこのように(または任意のテキストファイルオブジェクトを)呼び出すと、一度に1行ずつ暗黙的に読み取られます。次のステートメントは、等号の行を分割し、その部分を2つの変数に割り当てます。最後に、空白を取り除きkeyvalue辞書に保存します。

PS。line.split();を使用して、空白で行を分割することもできます。ただし、値または(可能性は低いですが)キーに埋め込みスペースが含まれていると、問題が発生します。

于 2012-04-11T20:50:26.600 に答える