![패턴 A가 있는 grep 파일이지만 패턴 B가 있는 파일은 제외됩니다.](https://linux55.com/image/155100/%ED%8C%A8%ED%84%B4%20A%EA%B0%80%20%EC%9E%88%EB%8A%94%20grep%20%ED%8C%8C%EC%9D%BC%EC%9D%B4%EC%A7%80%EB%A7%8C%20%ED%8C%A8%ED%84%B4%20B%EA%B0%80%20%EC%9E%88%EB%8A%94%20%ED%8C%8C%EC%9D%BC%EC%9D%80%20%EC%A0%9C%EC%99%B8%EB%90%A9%EB%8B%88%EB%8B%A4..png)
패턴 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 …
파일을 찾을 수 있는 곳아니요라인이 일치합니다.- 옵션
-q
은grep
의 공식적인 동의어이지만--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 정규식 엔진을 호출합니다.