패턴 A가 있는 grep 파일이지만 패턴 B가 있는 파일은 제외됩니다.

패턴 A가 있는 grep 파일이지만 패턴 B가 있는 파일은 제외됩니다.

패턴 A(iwant)를 포함하는 파일을 grep하고 싶지만 패턴 B(idontwant)를 포함하는 파일을 제외하고 싶습니다.

예:

read -p "...what are you looking for: " iwant
read -p "...what should not be included: " idontwant

iwant="blue car" 
idontwant="red car"

다음 파일이 있다고 가정해 보세요.

-rw-rw-r--.  1 terpentin terpentin  45 Jun  8 16:04 blue.car
-rw-rw-r--.  1 terpentin terpentin  44 Jun  8 16:05 mixed.car
-rw-rw-r--.  1 terpentin terpentin  40 Jun  8 16:04 red.car
find . -type f -print -exec cat {} \;

./mixed.car
blue car
red car
blue car

./red.car
red car
red car
red car

./blue.car
blue car
blue car
blue car

결과적으로 "./blue.car" 파일만 얻는 것이 어떻게 가능합니까?

원본 콘텐츠에는 수백 개의 긴 텍스트 파일이 포함되어 있으므로 리소스 효율성을 최대한 높이는 것이 중요합니다.

답변1

사용

find . -type f ! -exec grep -q "$idontwant" {} ';' -exec grep -q "$iwant" {} ';' -print

또는

find . -type f -exec grep -q "$iwant" {} ';' ! -exec grep -q "$idontwant" {} ';' -print
  • 명령의 용어(때때로 "술어"라고도 함)는 다음 find 과 같은 특성을 갖습니다.테스트(예:  -type f) 및행위(예:  -print및  -delete). 매뉴얼 페이지에서 알아내기 어려울 수도 있습니다.-exec행동그리고 시험. 그래서, 마찬가지로
    찾다 . -type f -mtime -30 -name '*.txt' -읽기 가능 -size +5테스트 6 테스트 7 테스트 8
    모든 기준을 충족하는(지정된 모든 테스트를 충족하는) 파일로 검색 범위를 연속적으로 좁힙니다.
    찾다 . -execcmd 1{} ';' -execcmd 2{} ';' -exec명령 3{} ';' …
    모든 명령이 성공한 파일을 찾습니다.
  • 모든 find테스트는 앞에 를 붙여 무효화(반전)할 수 있습니다 !. 따라서 find . ! -type d일반 파일, 심볼릭 링크, 명명된 파이프, 소켓 및 장치 파일(디렉터리를 제외한 모든 것)을 찾습니다.
  • ! -exec grep …와 동일하지 않습니다 -exec grep -v …-exec grep -v …일치하지 않는 줄이 하나 이상 있는 파일을 찾습니다.  ! -exec grep …파일을 찾을 것입니다.아니요라인이 일치합니다.
  • 옵션은 -q공식적 grep으로 의 동의어 --quiet이지만 다음을 의미하기도 합니다.빠른. 출력을 쓰지 않지만(해당하는 경우 오류 메시지 제외) 일치하는 항목을 찾으면 즉시 종료됩니다. 찾기 위해 모든 파일을 끝까지 읽지는 않습니다.모든성냥. (물론, 파일에 일치하는 항목이 없으면 grep전체 내용을 읽어서 이를 확인해야 합니다.)
  • 그래서 (TL;DR) 명령은 다음과 같은 파일을 찾습니다.
    grep -q "$iwan"     파일
    성공하고
    grep -q "$idontwant"파일
    실패합니다(앞에 가 있었기 때문입니다 !).
  • 두 명령은 기능적으로 동일하지만 성능이 다를 수 있습니다(즉, 실행하는 데 걸리는 시간이 다를 수 있음). 검색 문자열이 포함된 파일이 몇 개뿐인 경우
    찾다 . -type f -exec grep -q "$iwant" {} ';' ! -exec grep -q "$idontwant" {} ';' -인쇄
    grep "$iwant"대부분의 파일이 제거되므로 속도가 더 빨라집니다 . 많은 파일에 두 문자열이 모두 포함되어 있으면
    찾다 . -f를 입력하세요! -exec grep -q "$idontwant" {} ';' -exec grep -q "$iwant" {} ';' -인쇄
    ! grep "$idontwant"대부분의 파일이 제거되므로 속도가 더 빨라집니다 .

답변2

GNU grepregex 및 grep 옵션을 신중하게 선택하여 파일 이름 추출을 수행할 수 있습니다 .

$ grep -lzPsr '(?s:(?=.*blue)(?!.*red))' .

우리는 전체 파일이 하나의 큰 줄로 처리되는 slurp 모드(-z)에서 grep을 작동하고 있습니다.

-l은 정규식과 일치하는 파일의 파일 이름을 나열합니다.

-r은 아래 현재 디렉토리의 모든 파일에 대해 반복적으로 실행됩니다.

-s는 경고를 표시하지 않도록 grep을 침묵시킵니다.

정규식은 파일에 파란색이 있고 빨간색이 없는지 확인하여 '예'라고 답합니다.

-P는 grep에서 Perl 정규식 엔진을 호출하므로 pcre 정규식의 이점을 얻을 수 있습니다.

관련 정보