2012-04-11 3 views
0

저는 Python 초보자이며 여기 몇 가지 개념에 어려움을 겪고 있습니다. 도움이 필요합니다.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 

: 나는 "NFS = 등"밖으로 여분의 공백, 아니면 그냥 일명 AWK (세 번째 열을 것을 얻을 수있는 방법

[' 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'] 

을 '{인쇄 $ 3 } ') 그리고/또는 추가 조작을 위해 bash의 각 결과를 별도의 변수에 할당 할 수 있습니까?

이 학습 곡선을 설치하는 데 문제가있는 경우 도움을 진심으로 감사드립니다.

답변

1

세 번째 열은 line.split()[2]입니다. 처음 두 단어를 버리고 나머지를 가져 가려는 경우는 line.split(None, 2)[-1]입니다. (인수, 또는 제 1 인수로 Nonesplit가 공백에 분할한다.)

>>> ' 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 루프가 전달되고 이전 값은 잊어 버리는 반면 목록 이해력은 하나의 큰 목록을 구성합니다 먼저 각 단계에서 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)) 

이나, 파이썬 2.7/3,

다음은 물론

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

훨씬 좋네요, 두 개의 라인이 좀 더 읽기 쉽게 만들 수 있습니다

사전을 원 하든지 루프를 원 하든지 상관없이 처리하려는 처리 방법에 따라 다르지만 사전은 대부분의 경우 더 나은 방법 일 것입니다.

0

두 번째 질문 : 목록에서 결과를 수집 할 수 있지만 사전을 사용하는 것이 더 편리합니다.

첫 번째 질문 : 당신의 결과는 형태 key = value의 모든 때문에, 당신은 다음과 같이 압축을 해제 할 수 있습니다

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

이 같은 p.stdout (또는 텍스트 파일 오브젝트)를 호출, 그것은 암시에 한 줄을 읽어 시간. 다음 명령문은 등호의 선을 나눠서 두 부분에 할당합니다. 마지막으로 keyvalue 주위의 공백을 제거하고 사전에 저장합니다.

추신. line.split()으로 공백에 줄을 나눌 수도 있습니다. 그러나 키에 값 또는 (가능성이 적은) 키가 포함 된 공간을 포함하면 문제가 발생할 수 있습니다.

관련 문제