연속 된 두 줄의 내용을 기반으로 디렉토리를 grep하려면 어떻게해야합니까?


11

"Foo"가 포함 된 줄 의 디렉토리 를 어떻게 grep 할 수 있습니까? 다음 줄에도 "Bar"가있을 때만 일치합니까?


문제는 이제 원래와 완전히 다릅니다 : / 이전 버전을 되돌리고 다른 버전을 POST하는 것이 더 좋을까요? 또한 새로운 질문은 분명하지 않습니다.
Gilles Quenot

@ sputnick-어떻게 그렇게? 질문을 처음 게시했을 때 디렉토리를 지정했습니다. 사람들이 눈치 채지 못했기 때문에 대담했습니다.
Nathan Long

신경 쓰지 마라. 그것이 효과가있다. 나는 POST를 적절히 편집 할 것이다.
Gilles Quenot

답변:


7

@ warl0ck는을 (를) 올바른 방향으로 가리 켰지 pcregrep만 "is"가 아니라 "contains"라고 말했고 파일이 아닌 디렉토리에 대해 물었습니다.

이것은 나를 위해 작동하는 것 같습니다.

pcregrep -rMi 'Foo(.*)\n(.*)Bar' .

6

Grep 자체는이를 지원하지 않는 것 같습니다. 대신 pcregrep을 사용하십시오.

Foo
Bar
Foo
abc

pcregrep -M "Foo\nBar" file

있어 :

Foo
Bar

3
영업 이익은 그런 말을하지 않았다 FooBar전체 라인을 포함하는 것입니다.
tojrobinson

6

A의 sed스크립트 :

#!/bin/sed -nf

/^Foo/{
    h         # put the matching line in the hold buffer
    n         # going to nextline
    /^Bar/{   # matching pattern in newline
        H     # add the line to the hold buffer
        x     # return the entire paragraph into the pattern space
        p     # print the pattern space
        q     # quit the script now
    }
}

그것을 사용하려면 :

chmod +x script.sed
printf '%s\n' * | ./script.sed

printf여기에 한 줄에 각각 현재 디렉토리에있는 모든 파일을 표시하고에 전달 sed.

참고 : 이것은 알파벳 순서로 정렬됩니다.

유용 pattern space하고 hold space 여기에 대한 더 많은 정보 .

grymoire.comshell프로그래밍 에 대한 좋은 점이 있습니다 .


무엇을 h, n, H, x, p, q의미합니까? 매우 흥미로운.
Yamaneko

내 의견을 참조하십시오. 에 대한 자세한 정보를 정기적으로 pattern space& hold space: grymoire.com/Unix/Sed.html#uh-56 또는 프랑스어에서 commentcamarche.net/faq/9536-sed-introduction-a-sed-part-i
질 Quenot

POST는 디렉토리에서 작동하도록 적응
Gilles Quenot

4

다음을 사용 grep하여 다음 파이프를 구성 할 수 있습니다.

grep -A1 'Foo' input_file | grep -B1 'Bar' | grep 'Foo'

첫 번째 grepFoo일치하는 줄뿐만 아니라 포함 된 모든 줄을 가져옵니다 . 그런 다음 Bar일치하기 전에 줄뿐만 아니라 포함 하는 줄을 가져 와서이 출력에서을 포함하는 줄을 추출합니다 Foo.

편집 :manatwork는 지적의 관찰력이 될 몇 가지 문제가있는 경우가 있습니다. grep라인 지향 기능 으로 인해 흥미로운 과제가 있지만 , 그 솔루션을 사용하는 솔루션은 '해킹'이 될 수 있으며 pcregrep현재 작업에 더 적합한 것을 사용하는 것이 좋습니다 .


좋은. 나는 디렉토리에 관해 물었다. 이것은 작동하는 것 같습니다 :find . -name '*.txt' | xargs grep -A1 'Foo' | grep -B1 'Bar'
Nathan Long

또한 같은 줄에 "Foo"와 "Bar"가 모두있는 항목이 나열됩니다.
manatwork

@manatwork : "Foo"와 "Bar"가 포함 된 줄은 "Foo"가 포함 된 줄입니다.
tojrobinson

1
@tojrobinson, " 다음 줄에"Bar "가 포함 된 경우 에만 일치합니까?" pastebin.com/Yj8aeCEA
manatwork

3

을 사용하는 Nathan의 솔루션을 선호하지만 pcregrepgrep 만 사용하는 솔루션이 있습니다.

grep -o -z -P  'Foo(.*)\n(.*)Bar' file

옵션 설명 :

  • -o일치하는 부분 만 인쇄하십시오. 포함 후 필요한 -z전체 파일을 인쇄합니다 (어딘가에 \ 0이없는 경우)
  • -z 입력을 행 세트로 취급하십시오. 각 행은 개행 대신 0 바이트 (ASCII NUL 문자)로 종료됩니다.
  • -P 펄 정규식 구문

편집 :이 버전은 일치하는 전체 줄을 인쇄합니다

    grep -o -P -z  '(.*)Foo(.*)\n(.*)Bar(.*)' file

1
멋진 트릭 무엇 -z. 전체 표현식 전후에 일부 "(. *)"는 일치하는 전체 행을 출력합니다. 현재는 "Foo"앞과 "Bar"뒤에 하위 문자열이 표시되지 않습니다.
manatwork

1

awk로 :

awk '/bar/ && prev != "" {print FILENAME ": " prev "\n" FILENAME ": " $0}
     /foo/ {prev=$0; next}
     {prev=""}' file1...

(AWK 제한에 대한 일반적인 참고 사항 : 일부 파일 이름 문자가 포함 된 "="할 수 있다면, 당신은 등을 통과해야한다는 점에주의 ./filename대신 filenameAWK에)

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