Grep 및 Python


78

Unix 명령 줄에서 정규식을 통해 grep을 사용하여 파일을 검색하는 방법이 필요합니다. 예를 들어 명령 줄에 입력 할 때 :

python pythonfile.py 'RE' 'file-to-be-searched'

정규식 'RE'을 파일에서 검색하고 일치하는 줄을 인쇄해야합니다.

내가 가진 코드는 다음과 같습니다.

import re
import sys

search_term = sys.argv[1]
f = sys.argv[2]

for line in open(f, 'r'):
    if re.search(search_term, line):
        print line,
        if line == None:
            print 'no matches found'

하지만 존재 no matches found하지 않는 단어를 입력하면 인쇄되지 않습니다.


1
grep에서 파이썬 스타일 정규식을 정말로 원한다면 grep에 대한 --perl-regex 옵션이 정말 가깝습니다. Perl 스타일의 정규식 지원을 제공합니다. (또한, 그렙에 나의 마음에 드는 과소 옵션은 항상 --color =입니다)
로스 로저스

답변:


82

당연한 질문은 왜 grep을 사용하지 않는 것입니까?! 하지만 당신이 할 수 없다고 가정하면 ...

import re
import sys

file = open(sys.argv[2], "r")

for line in file:
     if re.search(sys.argv[1], line):
         print line,

참고할 사항 :

  • searchmatch문자열의 아무 곳이나 찾는 대신
  • 캐리지 리턴 ,print제거한 후 쉼표 ( ) (줄에 하나가 있음)
  • argv 파이썬 파일 이름을 포함하므로 변수는 1부터 시작해야합니다.

이것은 여러 인수를 처리하거나 (grep처럼) 와일드 카드를 확장하지 않습니다 (유닉스 셸처럼). 이 기능을 원하면 다음을 사용하여 얻을 수 있습니다.

import re
import sys
import glob

for arg in sys.argv[2:]:
    for file in glob.iglob(arg):
        for line in open(file, 'r'):
            if re.search(sys.argv[1], line):
                print line,

7
루프를 사용하기 전에 정규식을 컴파일해야합니다.
ghostdog74 2009

5
이것은 두 개의 반대표를 가지고 있으며 이유를 모릅니다. 반대표를 던진 사람이 댓글을 남기고 싶으십니까? 정규식 컴파일 등을 추가 할 수 있다는 것을 알고 있지만 대답의 명확성을 떨어 뜨릴 것이라고 생각했습니다. 내가 잘못 거기에 아무것도 생각하지 않는다, 나는 다른 답변의 일부와는 달리, 코드를 실행했습니다
닉 Fortescue의

이 답변은 저에게 완벽했습니다. 감사합니다. 일치하는 항목이 없으면 어떻게 인쇄해야하나요?
David

6
"루프를 사용하기 전에 정규식을 컴파일해야합니다.", 아니요, Python은 자체적으로 컴파일하고 캐시합니다. 이것은 일반적인 통념입니다. 가독성을 위해 좋은 일입니다.
bartekbrak

4
자연스러운 질문에 대한 합리적인 대답은 "코드가 훨씬 더 큰 Python 스크립트의 일부이기 때문에 그런 경우 누가 grep을 호출하겠습니까?"입니다. 요컨대, bash 스크립트를 시스템에서 더 쉬운 Python 스크립트로 대체했기 때문에이 질문이 여기에 있다는 것이 기쁩니다.
Mike S

13

간결하고 효율적인 메모리 :

#!/usr/bin/env python
# file: grep.py
import re, sys

map(sys.stdout.write,(l for l in sys.stdin if re.search(sys.argv[1],l)))

egrep (너무 많은 오류 처리없이)처럼 작동합니다. 예 :

cat input-file | grep.py "RE"

그리고 여기에 한 줄짜리가 있습니다.

cat input-file | python -c "import re,sys;map(sys.stdout.write,(l for l in sys.stdin if re.search(sys.argv[1],l)))" "RE"

7

pythongrep에서 수정되었습니다 .

를 통해 파일 이름 목록을 허용하고 [2:]예외 처리를하지 않습니다.

#!/usr/bin/env python
import re, sys, os

for f in filter(os.path.isfile, sys.argv[2:]):
    for line in open(f).readlines():
        if re.match(sys.argv[1], line):
            print line

sys.argv[1]resp sys.argv[2:]는 독립 실행 형 실행 파일로 실행하면 작동합니다.

chmod +x

먼저


re.match 과 의 차이점은 무엇 re.search입니까?
OscarRyz

2
@OscarRyz 참조 Nick Fortescue의 최상위 답변 : " 문자열의 아무 곳이나 찾는 search대신 match"
icc97

4
  1. sys.argv명령 줄 매개 변수를 가져 오는 데 사용
  2. 사용 open(), read()파일을 조작 할 수
  3. Python re 모듈 을 사용하여 줄을 일치 시킵니다.

3

pyp에 관심이있을 수 있습니다 . 내 다른 대답을 인용하면 :

"The Pyed Piper"또는 pyp는 awk 또는 sed와 유사한 Linux 명령 줄 텍스트 조작 도구이지만, 표준 Python 문자열 및 목록 메서드는 물론 강력한 프로덕션 환경에서 빠른 결과를 생성하도록 진화 된 사용자 지정 함수를 사용합니다.


1

python-textops3 사용할 수 있습니다.

from textops import *

print('\n'.join(cat(f) | grep(search_term)))

python-textops3를 사용하면 파이프와 함께 유닉스와 유사한 명령을 사용할 수 있습니다.


0

진짜 문제는 변수 라인에 항상 값이 있다는 것입니다. "일치하는 항목 없음"에 대한 테스트는 일치 항목이 있는지 여부이므로 "if line == None :"코드를 "else :"로 바꿔야합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.