파이프를 통해 grep -v로 찾기

파이프를 통해 grep -v로 찾기

특정 문자열을 포함하지 않는 특정 유형의 모든 파일을 찾으려고 합니다. grep -v에 find를 연결하여 이 문제를 해결하려고 합니다.

예:

find -type f -name '*.java' | xargs grep -v "something something"

이것은 작동하지 않는 것 같습니다. find 명령으로 찾은 모든 파일을 반환하는 것 같습니다. 내가 원하는 것은 기본적으로 특정 파일 이름과 일치하고(예: SessionPb.java에서 "Pb"로 끝나는) 내부에 "extends SomethingSomething"이 없는 모든 .java 파일을 찾는 것입니다.

내가 뭔가 잘못하고 있는 것 같아요. 그렇다면 명령은 어떤 모습이어야 할까요?

답변1

여기에는 필요가 없습니다 xargs. 또한 grepwith 옵션(일치하지 않는 파일)을 사용해야 합니다 -L. 그렇지 않으면 예제에서와 같이 이름 대신 파일 내용이 출력됩니다.

find . -type f -iname "*.java" -exec grep -L "something somethin" {} \+

답변2

너 진짜 얻으려고 하는구나...

find . -type f -iname "*.java" -print0 | xargs -0 grep -v "something something"

여기에서 시작하려면 "."을 클릭하세요. (당신은 암시하고 있지만 결코 가정하지는 않습니다).

-내 이름만일의 경우에 대비해 대소문자를 구분하지 않는 검색을 사용하세요.
-0을 인쇄하세요.파일 이름을 뒤에 \x00 문자와 함께 xargs로 보내면 공백이 포함된 파일 이름과 관련된 문제를 방지할 수 있습니다.

xargs의 "-0"은 반환되지 않고 \x00으로 끝나는 파일 이름이 예상됨을 나타냅니다.

그리고 당신의 grep 명령 ...

거의 다 됐어요.


편집하다::

귀하의 업데이트:

find . -type f -iname "*pb.java" -print0 | xargs -0 grep -iL "something"

도움이 될 것입니다. (@rush의 답변에 -L을 추가했습니다. 잘하셨습니다)

귀하의 grep에는 "-i" 옵션이 필요하거나 덜 명확하다고 생각합니다.

명령을 부분적으로 시도해 보십시오. 출력 파일 이름이 올바르게 보입니까?

find . -type f -iname "*pb.java"

그렇다면 문제는 grep 검색 패턴이 일치하지 않거나(철자가 틀리나요? 그런 일이 발생합니다!) 일치하는 항목이 없다는 것일 수 있습니다.

절대적인 최악의 시나리오:

grep -riL "something" *

모든 것을 검색하기 위해 더 많은 작업을 수행하지만 일부 결과를 제공해야 합니다.

답변3

컴퓨터는 컴퓨터입니다. 컴퓨터는 사용자가 원하는 대로 수행하는 것이 아니라 사용자가 지시한 대로 수행합니다.

grep -v "something something"포함되지 않은 모든 줄을 인쇄합니다 something something. 예를 들어 다음 세 줄 중 두 줄을 인쇄합니다.

hello world
this is something something
something else

extends SomethingSomething내용 없이 파일을 인쇄하려면 다음 -L옵션을 사용하십시오.

grep -L -E 'extends[[:space:]]+SomethingSomething' FILENAME…

-L일부 grep 버전에는 이 옵션이 없습니다 .POSIX). 쉘이 이 작업을 수행하지 않으면 아무것도 인쇄하지 않고 반환 코드를 사용하여 호출 쉘이 예상한 작업을 수행하도록 합니다.

grep -q -E 'extends[[:space:]]+SomethingSomething' FILENAME ||
echo "$FILENAME"

또는 awk를 사용하세요.

awk '
    FNR == 1 && NR != 1 && !found { print fn }
    FNR == 1 { fn = FILENAME; found = 0; }
    /extends[[:space:]]+SomethingSomething/ { found = 1 }
    END { if (fn != "" && !found) print fn }
'

Linux나 Cygwin(또는 GNU grep을 사용하는 다른 시스템)에서는 재귀가 가능하므로 find사용할 필요가 없습니다 .grep

grep -R --include='*.java' -L -E 'extends[[:space:]]+SomethingSomething'

쉘이 ksh, bash 또는 zsh인 경우 쉘이 파일 이름 일치를 수행하도록 할 수 있습니다. Bash에서는 set -o globstar먼저 실행하십시오(이것을 에 넣을 수 있습니다 ~/.bashrc).

grep -L -E 'extends[[:space:]]+SomethingSomething' **/*.java

답변4

find -type f -name '*.java' 2>&1 | grep -v "something something"

"grepping out"한 내용은 stdout이 아닌 stderr에 표시됩니다.

위 명령은 stderr를 stdout으로 리디렉션합니다.

원천

관련 정보