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

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

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

예:

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' -읽을 수 있는 크기 +5테스트 6 테스트 7 테스트 8
    모든 기준을 충족하는(지정된 모든 테스트를 만족하는) 파일로 검색 범위를 지속적으로 좁힙니다.
    찾다. -구현하다명령 1{} ';' -구현하다명령 2{} ';' -구현하다명령 3{} ';'
    모든 명령이 성공한 파일을 찾습니다.
  • 모든 find테스트는 앞에 를 붙여 무효화(반전)할 수 있습니다 !. 따라서 find . ! -type d일반 파일, 심볼릭 링크, 명명된 파이프, 소켓 및 장치 파일(디렉토리를 제외한 모든 것)을 찾을 수 있습니다.
  • ! -exec grep …와 같지 않습니다 -exec grep -v …-exec grep -v …일치하지 않는 줄이 하나 이상 있는 파일이 검색됩니다.  ! -exec grep …파일을 찾을 수 있는 곳아니요라인이 일치합니다.
  • 옵션 -qgrep의 공식적인 동의어이지만 --quiet다음을 의미하기도 합니다.빠른. 출력을 쓰지 않으며(해당하는 경우 오류 메시지 제외) 일치 항목이 발견되면 종료됩니다. 각 파일을 끝까지 읽지 않습니다.모든성냥. (물론 파일에 일치하는 항목이 없으면 grep전체 내용을 읽어야 확실하게 알 수 있습니다.)
  • 그래서(긴 이야기 짧게) 해당 파일을 찾는 명령
    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 grep정규식 및 grep 옵션을 현명하게 선택하여 파일 이름 추출을 수행 할 수 있습니다 .

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

전체 파일이 한 줄로 처리되는 slurp 모드(-z)에서 grep을 실행합니다.

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

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

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

정규식은 "예"라고 대답하기 위해 파일에 파란색이 있고 빨간색이 없는지 찾습니다.

-P는 pcre 정규식을 활용할 수 있도록 grep에서 Perl 정규식 엔진을 호출합니다.

관련 정보