grep -v로 파이프 찾기


18

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

예:

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

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

내 잘못은 내가 잘못하고 있다는 것입니다. 그렇다면 명령은 어떻게 생겼을까 요?


작동하지 않았다고 생각되는 것을 추가 할 수 있습니다. 아마도 당신의 grep 표현이 너무 명백합니까? 무의미한 경우 '-i'가 필요합니까? 아래 답변도 참조하십시오.
lornix

답변:


21

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

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

1
-L의미하기 때문에 이미 협상 중 files _without_ match입니다. 따라서 -v여기서 옵션이 필요하지 않습니다 .
rush

3
끝에 여분의 +가 없습니다.
lynxlynxlynx

2
find -exec \+누군가를 쓸 때마다 @ user946850 은 xargs를 사용하는 것이 훨씬 낫다는 것을 알려줍니다. 댓글을 작성하기 전에 아무도 사람을 보지 않는 이유는 무엇입니까? (:
rush

5
@ user946850은와 -exec ... {} \+동일하지 않습니다 xargs. findutils 문서를 읽으십시오! (나는 열심히 노력했습니다!)
James Youngman

2
@ user946850 예. 차이점 중 하나는 기본적 xargs으로 입력을 처리하고 공백에서 인수를 분리 한다는 것 입니다. 따옴표도 기본적으로 특별합니다 xargs. 이것들 중 어느 것도 사실이 아닙니다 -exec ... {} +. 구 버전은 xargs밑줄을 EOF 지표로 간주하는 데 사용되었지만 더 이상 그렇지 않습니다.
James Youngman

7

당신은 거의 그것을 거의 얻었습니다 ...

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

점 '.' 여기서부터 시작한다고합니다. (당신은 그것을 암시하지만 결코 가정하지 마십시오)

-iname 은 대소 문자를 구분하지 않고 대소 문자를 구분하지 않는 검색을 사용합니다.
-print0 은 파일 이름에 공백이있는 \ 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" *

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


나는 당신의 수정을 시도했지만 여전히 내가 기대하는 결과를 얻지 못했습니다. 더 명확하게하기 위해 질문을 업데이트하려고합니다.
Hyangelo

질문의 작성자가 파일 이름 만 찾으려면 grep을 'grep -l -v'로 설정해서는 안됩니까?
브루스 에디 거

그는 * .java 파일에서 특정 내용을 찾고 있습니다
lornix

xargs -0 grep -v "something something"해야 xargs -0 grep -v "something something" /dev/null찾기가 일치하는 파일을 생성하지 않는 경우 그렇지 않으면 이상한 결과를 얻을 수 있습니다.
제임스 영먼

{Grin} 예, 어딘가에 논리가 모두 털이 있습니다. 머리를 다치게하는 거꾸로 된 허위 논리 다중 테스트와 같은 것은 없습니다.
lornix

4

컴퓨터는 컴퓨터입니다. 원하는 것을하는 대신에 말한 것을하고 있습니다.

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

hello world
this is something something
something else

포함되지 않은 파일을 인쇄하려면 extends SomethingSomething어디에도-L 옵션을 사용하십시오 .

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

grep의 일부 버전에는 -L옵션이 없습니다 ( 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

와우,이게 더 나아 내가 말할 수있는 한 작동하는 것처럼 보이는 'extends (/ s) + SomethingSomething'을 사용하고있었습니다. Extended RegEx 버전에 지정된 구문과이 구문에 차이가 있습니까?
Hyangelo

@Hyangelo \s는 GNU grep 확장이며, 나는 동의어라고 생각 [[:space:]]합니다.
Gilles 'SO- 악한 중지'
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.