2013-03-31 2 views
1

이 코드를 실행하면 grep : write 오류가 발생합니다. 내가 무엇이 누락 되었습니까?grep : 쓰기 오류 : 서브 프로세스가있는 파이프가 깨졌습니다.

이 그것의 일부이다 :

 while d <= datetime.datetime(year, month, daysInMonth[month]): 
     day = d.strftime("%Y%m%d") 
     print day 
     results = [day] 
     first=subprocess.Popen("grep -Eliw 'Algeria|Bahrain' "+ monthDir +"/"+day+"*.txt | grep -Eliw 'Protest|protesters' "+ monthDir +"/"+day+"*.txt", shell=True, stdout=subprocess.PIPE,) 
     output1=first.communicate()[0] 
     d += delta 
     day = d.strftime("%Y%m%d") 
     second=subprocess.Popen("grep -Eliw 'Algeria|Bahrain' "+ monthDir +"/"+day+"*.txt | grep -Eliw 'Protest|protesters' "+ monthDir +"/"+day+"*.txt", shell=True, stdout=subprocess.PIPE,) 
     output2=second.communicate()[0] 
     articleList = (output1.split('\n')) 
     articleList2 = (output2.split('\n')) 
     results.append(len(articleList)+len(articleList2)) 
     w.writerow(tuple(results)) 
     d += delta 
+0

난 당신이 뭘 하려는지 알아낼 수 없습니다. grep에 filename 인수를 주면 stdin에서 읽지 않습니다. 그래서 grep 프로세스의 출력을 두 번째 파이프로 파이프하는 이유는 무엇입니까? – Barmar

+0

나는 알제리 또는 바레인이라는 키워드와 항의 또는 항의를 포함하는 파일을 필터링하고 있습니다. 실제로이 질문을 위해 단순화 한 lil이 더 복잡합니다. list1에있는 키워드 중 하나와 list2에있는 키워드 중 하나를 포함하는 모든 파일을 가져 오려고합니다. –

+0

Python의 정규 표현식 라이브러리 인 're'을 사용하지 않은 특별한 이유는 무엇입니까? grep을 부르는 것을 막을 것입니다. –

답변

5

프로세스 A의 출력은 입력으로 프로세스 B에 파이프됩니다. 프로세스 A의 출력을 모두 읽기 전에 프로세스 B가 종료되면 (예 : -l 옵션의 기능인 찾고있는 것이 발견 되었기 때문에) 프로세스 A가 출력 파이프가 조기에 닫혔다 고 불평 할 수 있습니다.

이러한 오류는 기본적으로 무해하므로 하위 프로세스의 stderr/dev/null으로 리디렉션하여 해결할 수 있습니다.

더 좋은 방법,하지만, 단순히 파일을 읽을 파이썬의 강력한 정규 표현식 기능을 사용할 수 있습니다 :

def fileContains(fn, pat): 
    with open(file) as f: 
     for line in f: 
      if re.search(pat, line): 
       return True 
    return False 

first = [] 
for file in glob.glob(monthDir +"/"+day+"*.txt"): 
    if fileContains(file, 'Algeria|Bahrain') and fileContains(file, 'Protest|protesters'): 
     file.append(first) 
1

두 패턴과 일치하는 파일을 찾을 수있는 명령 구조 같아야

grep -l pattern1 $(grep -l pattern2 files) 

$(command) 명령 행으로 명령의 출력을 대입 .

그래서 스크립트는 다음과 같아야합니다

first=subprocess.Popen("grep -Eliw 'Algeria|Bahrain' $("+ grep -Eliw 'Protest|protesters' "+ monthDir +"/"+day+"*.txt)", shell=True, stdout=subprocess.PIPE,) 

당신은 단지 전체 단어를 찾는 경우 유사 second

+0

그것은 나를 위해 작동하지 않았다. 왜 내가 어떤 경우에는 파이프가 파손되고 어떤 경우에는 그렇지 않은지 설명 할 수 있습니까? 오류는 무엇을 의미합니까? –

+0

브로큰 파이프는 명령이 파이프에 쓰려고했지만 읽기 끝이 닫혔다는 것을 의미합니다. 'first.communicate()'를 사용할 때 일어날 것이라고 생각하지 않습니다. 왜냐하면 그것은 EOF까지 읽습니다. – Barmar

1

을 위해, 당신은 count() 멤버 함수를 사용할 수 있습니다;

# assuming names is a list of filenames 
for fn in names: 
    with open(fn) as infile: 
     text = infile.read().lower() 
    # remove puntuation 
    text = text.replace(',', '') 
    text = text.replace('.', '') 
    words = text.split() 
    print "Algeria:", words.count('algeria') 
    print "Bahrain:", words.count('bahrain') 
    print "protesters:", words.count('protesters') 
    print "protest:", words.count('protest') 

더 강력한 필터링을 원하면 re을 사용하십시오. 당신이 쉘에

A | B 

을 수행 할 때

관련 문제