2012-04-11 7 views
0

私はPythonの初心者です。ここでいくつかのコンセプトに苦しんでいます。Python2.6を使ってBashの出力を解析する

私は、データベースに問い合わせるカスタムシステムツールを持っていて、各行に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'] 

は(別名awkは「{$ 3印刷する方法を、私は「NFS =など」から、余分な空白を出すことができ、またはちょうど3番目の列を取ることを} ')、さらにこれらの結果の各部分をbashから別の変数に割り当てて、さらに操作することができますか?

この学習曲線がうまくいかない場合は、誠にありがとうございます。

答えて

1

第3列はline.split()[2]です。あなたが最初の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)path_outputの各値に対してl.split(None, 2)を実行ジェネレータ式、(ありますそれをlと呼ぶ)。それはリストの理解のようなものですが、()の代わりに[]の代わりに[]を使用していますが、l.splitコールが実行され、forループが通過してから以前の値を忘れてしまいます。リストの理解は1つの大きなリスト最初に各ステップで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) } 

非常に良く、次の2つの行に、この小さな読みやすくすることができ

辞書を使用するのか、ループのみを使用するのかは、使用する処理によって異なりますが、ほとんどの場合、辞書はおそらくより良いアプローチです。

0

第2の質問第1の質問:リスト内で結果を収集することはできますが、辞書を使用する方が手軽です。

最初の質問:あなたの結果は、すべてのフォームkey = valueであるので、あなたがこのようにそれらを抽出することができます。

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

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

PS。あなたはまた、空白で行を分割することもできます。line.split();キーに値が埋め込まれている場合や、キーに埋め込みスペースが含まれている場合は、問題が発生します。

関連する問題