두 단어 중 하나만 포함하고 둘 다 포함하지 않는 줄을 찾으려면 어떻게 해야 합니까?

두 단어 중 하나만 포함하고 둘 다 포함하지 않는 줄을 찾으려면 어떻게 해야 합니까?

grep이 두 단어 중 하나만 줄에 표시되고 같은 줄에 있으면 표시되지 않는 두 단어 중 하나를 포함하는 줄만 표시 하려고 합니다 .

지금까지 시도했지만 grep pattern1 | grep pattern2 | ...예상한 결과를 얻지 못했습니다.

답변1

그 이외의 도구는 grep갈 길입니다.

예를 들어, Perl을 사용하면 명령은 다음과 같습니다.

perl -ne 'print if /pattern1/ xor /pattern2/'

perl -nestdin의 각 줄에 지정된 명령을 실행합니다. 이 경우 일치하는 경우 줄을 인쇄합니다. 즉, /pattern1/ xor /pattern2/한 패턴은 일치하지만 다른 패턴은 일치하지 않습니다(XOR).

이는 패턴 순서에 관계없이 작동하며 grep여러 호출보다 성능이 뛰어나고 입력이 적습니다.

또는 더 짧게 awk를 사용하세요.

awk 'xor(/pattern1/,/pattern2/)'

또는 다음이 없는 awk 버전의 경우 xor:

awk '/pattern1/+/pattern2/==1`

답변2

GNU를 사용하면 두 단어를 전달한 다음 두 패턴이 모두 포함된 줄을 삭제할 grep수 있습니다 .grep

$ cat testfile.txt
abc
def
abc def
abc 123 def
1234
5678
1234 def abc
def abc

$ grep -w -e 'abc' -e 'def' testfile.txt | grep -v -e 'abc.*def' -e 'def.*abc'
abc
def

답변3

사용해 보세요egrep

egrep  'pattern1|pattern2' file | grep -v -e 'pattern1.*pattern2' -e 'pattern2.*pattern1'

답변4

부울 용어로 다음과 같이 쓸 수 있는 A xor B를 찾고 있습니다.

(B 대신 A)

또는

(A 대신 B)

귀하의 질문에 출력 순서에 관심이 있다는 것이 언급되어 있지 않다면 일치하는 행이 표시되는 한 grep에서 A xor B의 부울 확장이 매우 간단합니다.

$ cat << EOF > foo
> a b
> a
> b
> c a
> c b
> b a
> b c
> EOF
$ grep -w 'a' foo | grep -vw 'b'; grep -w 'b' foo | grep -vw 'a';
a
c a
b
c b
b c

관련 정보