일부 패턴을 제외하고 grep하는 방법?


84

일부 패턴이 있고 다른 패턴이없는 파일에서 줄을 찾고 싶습니다. 예를 들어, 내가 포함한 모든 파일 / 라인을 찾을 필요 loom와 제외한를 gloom. 따라서 loom명령으로 찾을 수 있습니다 .

grep -n 'loom' ~/projects/**/trunk/src/**/*.@(h|cpp)

loom이제을 제외하고 검색 하고 싶습니다 gloom. 그러나 다음 두 명령이 모두 실패했습니다.

grep -v 'gloom' -n 'loom' ~/projects/**/trunk/src/**/*.@(h|cpp)
grep -n 'loom' -v 'gloom' ~/projects/**/trunk/src/**/*.@(h|cpp)

목표를 달성하려면 어떻게해야합니까?

편집 1 : 난 그 의미loomgloom문자 시퀀스 (반드시 단어가) 있습니다. 따라서 예를 들어bloomberg명령 출력에 필요하고ungloomy.

편집 2 : 내 기대치의 샘플이 있습니다. 다음 두 줄은 모두 명령 출력에 있습니다.

나는 향의 베일을 통해 어렴풋이 드러나는 아이콘을 마주했다 .

Arty는 우울한 날에 어둡 습니다 .

다음 줄은 모두 명령 출력에 없습니다.

그것은이다 'gloomyin cloods - 오 좋은 muckle doolders 심고 끔찍한'.

heigh pyntit 홀의 남서쪽 라운드에서


기준과 일치하는 행 기준과 일치하는 파일을 찾고 있습니까?
Juto 2013-08-27

내 기준과 일치하는 줄이있는 파일을 찾고 있습니다. 그리고 모든 세트 파일 이름 + 일치하는 줄 수 + 일치하는 줄 자체의 목록을보고 싶습니다.
Loom

그 라인이 있다면 there is a loom in the gloom-그 라인을 인쇄 하시겠습니까? 단순히 어두움의 일부가 아닌 다른 라인이 발생하는 라인을 찾고 있거나 라인의 다른 곳에서 베틀이 자체적으로 나타날 때에도 어두움을 포함하는 라인을 정말로 제외하고 싶은지 이해하려고합니다. 샘플 입력과 예상 출력을 게시하면 도움이 될 것입니다.
Ed Morton

그래서 당신의 질문은 정말 How do I find lines containing the string "loom" where "loom" is not preceded by the letter "g"? 샘플 입력과 원하는 출력을 게시했다면 많은 도움이 될 것입니다. 그 질문에 대한 답변은 아래 답변에 포함되어 있습니다.
Ed Morton

1
@EdMorton은 - 예, 권리를하고 - 나는 발생하는 경우, 모든 행을 필요로 loom선행하지 않고 g. (죄송합니다. 어제 코멘트를 시작했지만 아직 끝나지 않았습니다. 실수로이 코멘트가 전송되었습니다.)
Loom

답변:


102

그립을 연결하는 것은 어떻습니까?

grep -n 'loom' ~/projects/**/trunk/src/**/*.@(h|cpp) | grep -v 'gloom'

13
제 시간에. 완벽하게 작동합니다. -v는 제외하는 옵션입니다. 감사합니다
Ravi Krishna P

2
질문에서 : 예를 들어 bloomberg명령 출력에 필요하고 ungloomy. 한 줄에 '… 그리고 블룸버그가 잠재 고객에 대해 어지럽다…'가 포함 된 경우 해당 줄을 제거 할 수 있지만 필요합니다 (이 포함 된 경우 bloomberg).
Jonathan Leffler

23

체인이없는 또 다른 솔루션 grep:

egrep '(^|[^g])loom' ~/projects/**/trunk/src/**/*.@(h|cpp)

괄호 사이에, 당신은 문자 제외 g의 발생 이전을 loom하지 않는 한 loom라인의 첫 번째 문자입니다.


9

조금 늙었지만 오 글쎄 ...

@houbysoft에서 가장 많이 투표 한 솔루션은 "loom"이 있더라도 "gloom"이 포함 된 라인을 제외하므로 작동하지 않습니다. OP의 기대에 따라 "loom"이 포함 된 라인도 포함해야합니다. 이 라인은 "Arty is slooming in a darky day."라는 출력에 있어야합니다.

grep -n 'loom' ~/projects/**/trunk/src/**/*.@(h|cpp) | grep -v 'gloom'

대신 Bentoy13egrep 정규식 예제가 더 잘 작동합니다.

egrep '(^|[^g])loom' ~/projects/**/trunk/src/**/*.@(h|cpp)

"gloom"이 있는지 여부에 관계없이 "loom"이있는 모든 라인을 포함합니다. 반면에 어둡기 만한다면 OP가 원하는 행동을 포함하지 않을 것입니다.


8

awk를 사용하면 복합 조건을 명확하게 표현할 수있는 grep보다 훨씬 간단합니다.

loomgloom다음을 모두 포함하는 줄을 건너 뛰려면

awk '/loom/ && !/gloom/{ print FILENAME, FNR, $0 }' ~/projects/**/trunk/src/**/*.@(h|cpp)

또는 인쇄하려는 경우 :

awk '/(^|[^g])loom/{ print FILENAME, FNR, $0 }' ~/projects/**/trunk/src/**/*.@(h|cpp)

그리고 현실이 당신 loom은 그 자체로 단어 로 나타나는 줄을 원하면 :

awk '/\<loom\>/{ print FILENAME, FNR, $0 }' ~/projects/**/trunk/src/**/*.@(h|cpp)

3
당신이 포함하는 행을 얻기 위해 grep 명령을 써서하는 방법에 대한 생각 abcdefghi임의의 순서로. 이제 그것을 awk '/abc/ && /def/ && /ghi/'. 이제이 awk '/loom/ && !/gloom/'페이지의 답변에서 grep에 해당하는 내용이 어떻게 작성 되는지 생각해보십시오 .
Ed Morton

나는 awk에별로 익숙하지 않다. 분명히이 명령 자체에 대한 책이있다. 지금은 grep으로 괜찮습니다. 언젠가는 당신이했던 것과 같은 말을 할 것입니다. :)
Juto 2013-08-28

2
awk는 텍스트 파일 처리를위한 표준 UNX 도구 (즉, 모든 UNIX 설치에서 사용 가능)입니다. 그것이하기 위해 발명 된 것이고 아주 잘합니다. UNIX에서 텍스트 파일을 구문 분석하는 경우 Arnold Robins의 Effective Awk Programming, Third Edition 책에서 awk를 배우십시오. awks condition { action }구문 과 관련된 작은 패러다임 전환이 있지만 C 또는 다른 Algol 기반 언어 경험이있는 사람이라면 누구나 쉽게 할 수 있습니다.
Ed Morton

보너스 : 다음과 같은 출력 grep -Hn --color:awk '/loom/ && !/gloom/ { gsub(/loom/, color("1;31") "&" color(0)); print color(35) FILENAME color(36) ":" color(32) FNR color(36) ":" color(0) $0; }; function color(c) { return "\033[" c "m"; }'
tangle

6

-v "inverted match"플래그이므로 파이핑은 매우 좋은 방법입니다.

grep "loom" ~/projects/**/trunk/src/**/*.@(h|cpp)| grep -v "gloom"


5

/ * 당신은 이런 식으로 보일 수 있습니까?

grep -vn "gloom" `grep -l "loom" ~/projects/**/trunk/src/**/*.@(h|cpp)`

BACKQUOTES는 명령의 대괄호처럼 사용되므로이 경우 -l활성화 된 경우 BACKQUOTES의 코드는 파일 이름을 반환 한 다음 -vn을 사용하여 원하는 작업을 수행합니다. 파일 이름, 줄 번호 및 실제 줄도 있습니다.

업데이트 또는 xargs 사용

grep -l "loom" ~/projects/**/trunk/src/**/*.@(h|cpp) | xargs grep -vn "gloom"

도움이되기를 바랍니다. * /

내가 위에 쓴 것을 무시하십시오. 쓰레기입니다.

grep -n "loom" `grep -l "loom" tt4.txt` | grep -v "gloom"

               #this part gets the filenames with "loom"
#this part gets the lines with "loom"
                                          #this part gets the linenumber,
                                          #filename and actual line

4

grep -P지원되는 (perl regex) 사용할 수 있습니다 negative lookbehind.

grep -P '(?<!g)loom\b' ~/projects/**/trunk/src/**/*.@(h|cpp)

\b단어 경계를 추가 했습니다.


2
당신은 뒤를 볼 필요가 없습니다 \([^g]\|^\). 그리고 이것은 loomgloom.
Kevin

@Kevin : OP는 베틀로 라인을 찾고 싶지만 not gloom.
anubhava

바로 그거죠. 라인에 두 가지가 모두 있으면 원하지 않지만 어쨌든 일치합니다.
Kevin

@Kevin : 이것은 gloom과 일치하지 않지만 (OP가 원하는대로) loom과 일치합니다.
anubhava

질문에서 : 예를 들어 bloomberg명령 출력에 필요하고 ungloomy. 따라서 단어 경계는 비생산적입니다.
Jonathan Leffler

3
grep -n 'loom' ~/projects/**/trunk/src/**/*.@(h|cpp) | grep -v 'gloom'

질문에서 : 예를 들어 bloomberg명령 출력에 필요하고 ungloomy. 한 줄에 '… 그리고 블룸버그가 잠재 고객에 대해 어지럽다…'가 포함 된 경우 해당 줄을 제거 할 수 있지만 필요합니다 (이 포함 된 경우 bloomberg).
Jonathan Leffler

@JonathanLeffler "어두운 파일을 제외한 모든 파일 / 라인을 찾아야합니다."
Jiminion 2017-06-27

3

간단히 사용하세요! grep -v여러 번.

파일 내용

[root@server]# cat file
1
2
3
4
5

줄 또는 일치 제외

[root@server]# cat file |grep -v 3
1
2
4
5

라인을 제외하거나 여러 개 일치

[root@server]# cat file |grep -v 3 |grep -v 5
1
2
4

0

질문 : 'gloom'을 제외한 'loom'을 검색합니다.
대답:

grep -w 'loom' ~/projects/**/trunk/src/**/*.@(h|cpp)

1
질문에서 : 예를 들어 bloomberg명령 출력에 필요하고 ungloomy. 나는 그것이 -w그 수수께끼에 대한 해결책 이라고 생각하지 않습니다 .
Jonathan Leffler
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.