파일에서 여러 줄 패턴을 어떻게 검색합니까?


128

특정 문자열 패턴이 포함 된 모든 파일을 찾아야했습니다. 염두에 두어야 할 첫 번째 해결책은 xargs grep으로 find piped를 사용하는 것입니다 .

find . -iname '*.py' | xargs grep -e 'YOUR_PATTERN'

그러나 두 줄 이상에 걸쳐있는 패턴을 찾아야한다면 바닐라 그렙이 여러 줄 패턴을 찾을 수 없기 때문에 붙어 있습니다.



2
이 사람의 나이, 나는 그것이 중복 :) 아니다라고 말하고 싶지만 그래서
rogerdpack

@rogerdpack 질문을 중복으로 표시 할 때, 질문의 나이는 답변의 양과 질, 질문의 질에 따른 3 차 문제입니다.
tripleee

답변:


98

그래서 Perl Compatible Regular Expressions GREP의 약자 인 pcregrep 을 발견 했습니다 .

예를 들어, ' _name '변수 바로 뒤에 ' _description '변수 가있는 파일을 찾아야합니다 .

find . -iname '*.py' | xargs pcregrep -M '_name.*\n.*_description'

팁 : 패턴에 줄 바꿈 문자를 포함해야합니다. 플랫폼에 따라 '\ n', \ r ','\ r \ n '등이 될 수 있습니다.


7
아래의 halka에서 언급했듯이 "정규 표현식에 (? s)를 추가하면 점 와일드 카드를 사용하여 줄 바꿈과 일치시킬 수도 있습니다." 그런 다음 -P를 추가하여 perl 정규식과 함께 grep을 사용하십시오. 찾기 . -exec grep -nHP '(? s) SELECT. {1,60} FROM. {1,20} table_name' '{}'\;
Jim

8
pcregrepMac에서 다음과 같이 사용할 수 있습니다brew install pcre
Jared Beck

1
더 나은 : 또한 -H일치하기 전에 파일 이름을 인쇄하는을 사용 하십시오 pcregrep -HM.
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功

97

awk에 가지 않습니까 ?

awk '/Start pattern/,/End pattern/' filename

2
이것은 awk대부분의 * nix 시스템과 함께 제공 되는 이해 및 사용이 훨씬 쉽습니다 .
알리 카르 바시

24
좋은! 이 경기를 탐욕스럽지 않게 만드는 방법이 있습니까?
marcin

3
일치하는 파일 이름 만 어떻게 인쇄합니까?
bibstha

2
로 일치하는 줄 번호를 표시 할 수 있습니다 awk '/Start pattern/,/End pattern/ {printf NR " "; print}' filename. 줄 번호에 고정 너비를 지정하여 더 예쁘게 만들 수 있습니다 awk '/Start pattern/,/End pattern/ {printf "%-4s ", NR; print}' filename.
Robert

이것은 단일 파일에서 잘 작동하는 것처럼 보이지만 여러 파일 내에서 검색하려면 어떻게해야합니까?
Jinstrong

84

다음은 GNUgrep 를 사용하는 예입니다 .

grep -Pzo '_name.*\n.*_description'

-z/--null-data 라인의 순서로 처리를 입력 및 출력 데이터.

여기도 참조


1
그것은 하나의 개행 문자만을 설명한다고 생각합니다.
Cloud

1
플래그를 사용 -z하지 않고 여러 줄 검색에 grep을 사용할 수 없었기 때문에 한 줄로 검색을 분할하지 않고 -o일치하는 부분 만 인쇄했습니다.
bbaja42

나는 -o로 인해 아무것도 인쇄하지 않는 것을 발견했지만 -l은 파일 목록을 얻기 위해 일했습니다 (내 명령은 grep -rzl pattern *-rzo가 작동하지 않았습니다)
Benubird

5
비 ASCII 파일의 경우 ''-Pzo ''대신 '' grep -Pazo ''를 권장 합니다. 비 ASCII 파일의 -z 스위치는 grep의 "이진 데이터"동작을 트리거하여 반환 값을 변경할 있기 때문에 더 좋습니다 . 스위치 ''-a | --text ''는이를 방지합니다.
rloth

git가 설치된 Mac에서 작동하지 않음brew reinstall --with-pcre git
Quanlong

21

grep -Plibpcre도 사용하지만 훨씬 더 광범위하게 설치됩니다. titlehtml 문서 의 전체 섹션 을 찾으려면 여러 줄에 걸쳐 있어도 다음을 사용할 수 있습니다.

grep -P '(?s)<title>.*</title>' example.html

이후 PCRE 프로젝트 펄 표준을 구현, 참조를 위해 펄 문서를 사용합니다 :


흠 지금이 시도하고 작업 ...에 보이지 않았다 gist.github.com/rdp/0286d91624930bd11d0169d6a6337c33
rogerdpack

grep 에이 옵션이 있다는 것을 몰랐 습니다. 아마도 이것으로 인해 : 이것은 매우 실험적이며 grep -P는 구현되지 않은 기능에 대해 경고 할 수 있습니다. ; Fedora 29에서 : 이것은 실험적이며 grep-P는 구현되지 않은 기능에 대해 경고 할 수 있습니다 . 물론 BSD grep에는 전혀 없습니다. 그것이 실험적이지 않으면 좋을 것입니다.하지만 그것을 생각 나게하는 것이 좋습니다.
Pryftan

17

더 유용한 예는 다음과 같습니다.

pcregrep -Mi "<title>(.*\n){0,5}</title>" afile.html

제목 줄은 최대 5 줄로 표시 되더라도 html 파일에서 제목 태그를 검색합니다.

무제한 라인의 예는 다음과 같습니다.

pcregrep -Mi "(?s)<title>.*</title>" example.html 

4
이것에 감사합니다. 와일드 카드가 줄 바꿈 문자와 일치하지 않는다는 사실을 깨닫지 못했습니다.
matt

7
@matt : (?s)정규식에 다음과 같이 추가하면 개행 문자와 일치하도록 점 와일드 카드를 설득 할 수 있습니다 ."(?s)<html>.*</html>"
lubomir.brindza

@matt 물론 당신은 $(패턴의 끝에서) 그것이 줄의 끝임 을 나타 내기 위해 점검 할 수 있습니다. 그러나 여러 줄 패턴을 찾는 데 도움이되는 것은 아닙니다. 도 참조하십시오 glob(7). : 당신은 또한 관심의이 웹 사이트를 찾을 수 regular-expressions.info
Pryftan


4

grep alternative sift를 사용할 수 있습니다 (면책 조항 : 저자입니다).

여러 줄 일치를 지원하고 검색을 특정 파일 형식으로 제한합니다.

sift -m-파일 '* .py' 'YOUR_PATTERN'

(지정된 여러 줄 정규식 패턴에 대한 모든 * .py 파일을 검색하십시오)

모든 주요 운영 체제에서 사용할 수 있습니다. 상기 살펴보세요 샘플 페이지 가 XML 파일에서 여러 값을 추출하는 방법을 참조하십시오.


3

이 답변은 유용 할 수 있습니다.

여러 줄 검색을위한 정규식 (grep)

재귀 적으로 찾기 위해 플래그 -R (재귀) 및 --include (GLOB 패턴)를 사용할 수 있습니다. 보다:

grep --exclude /-include 구문을 사용하여 특정 파일을 grep하지 마십시오.


@ Ɖiamond ǤeezeƦ LQP에서 게시물을 편집하면 ( stackoverflow.com/review/low-quality-posts/19341146 ) 검토가 무효화되므로 게시물을 유지 관리해야한다고 확신하면 편집하면됩니다.
fedorqui 'SO 중지 피해'

2

@Marcin : awk 예제 비 욕심 :

awk '{if ($0 ~ /Start pattern/) {triggered=1;}if (triggered) {print; if ($0 ~ /End pattern/) { exit;}}}' filename

2
perl -ne 'print if (/begin pattern/../end pattern/)' filename

이것은 전체 파일을 인쇄합니다
Herbert

1

사용 ex/ vi편집기와 globstar 옵션 (유사 구문 awksed) :

ex +"/string1/,/string3/p" -R -scq! file.txt

aaa시작점이 어디 이며 bbb끝 텍스트입니다.

재귀 적으로 검색하려면 다음을 시도하십시오.

ex +"/aaa/,/bbb/p" -scq! **/*.py

참고 : **구문 을 사용하려면 shopt -s globstar(Bash 4 또는 zsh)를 실행하십시오.

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