텍스트 파일에서 ‘word1’XOR ‘word2’가있는 줄을 검색하고 싶습니다. 따라서 word1, word2가있는 행을 출력해야하지만이 단어가 모두있는 행은 출력하지 않아야합니다. XOR을 사용하고 싶었지만 Linux 명령 줄에 작성하는 방법을 모르겠습니다.
나는 시도했다 :
grep 'word1\|word2' text.txt
grep word1 word2 text.txt
grep word1 text.txt | grep word2
grep 'word1\^word2' text.txt
그리고 더 많은,하지만 성공하지 못했습니다.
답변
grep 'word1\|word2' text.txt
라인 수용 검색 word1
하거나 word2
. 여기에는 둘 다 포함 된 줄이 포함됩니다.
grep word1 text.txt | grep word2
함유 라인을 검색 word1
하고 word2
. 두 단어 (예를 겹칠 수 foobar
포함 foo
하고 ob
). 겹치지 않는 방식으로 만 두 단어를 모두 포함하는 행을 검색하는 다른 방법은 다음 순서로 검색하는 것입니다.grep 'word1.*word2\|word2.*word1' text.txt
grep word1 text.txt | grep -v word2
포함 word1
하지만 포함 하지 않는 행을 검색합니다 word2
. 이 -v
옵션은 grep에게 일치하지 않는 행을 유지하고 일치하는 행을 제거하도록 지시합니다. 이렇게하면 원하는 결과의 절반이 제공됩니다. 대칭 검색을 추가하면 정확히 하나의 단어를 포함하는 모든 줄을 얻을 수 있습니다.
grep word1 text.txt | grep -v word2
grep word2 text.txt | grep -v word1
또는 한 단어가 포함 된 줄에서 시작하여 두 단어가 포함 된 줄을 제거 할 수 있습니다. 위의 빌딩 블록이 주어지면 단어가 겹치지 않으면 쉽습니다.
grep 'word1\|word2' text.txt | grep -v 'word1.*word2\|word2.*word1'
답변
GNU로 awk
:
$ printf '%s\n' {foo,bar}{bar,foo} neither | gawk 'xor(/foo/,/bar/)'
foofoo
barbar
또는 휴대용으로 :
awk '((/foo/) + (/bar/)) % 2'
A를 grep
위한과 지원 -P
(PCRE) :
grep -P '^((?=.*foo)(?!.*bar)|(?=.*bar)(?!.*foo))'
로 sed
:
sed '
/foo/{
/bar/d
b
}
/bar/!d'
당신이 (어느 쪽이 없음을 전체 단어 만 고려할 경우 foo
도 bar
에 foobar
또는 barbar
예를 들어), 당신은 그 단어를 구분하는 방법을 결정해야합니다 것입니다. -w
많은 grep
구현 옵션 과 같이 문자, 숫자 및 밑줄 이외의 문자 가 있으면 다음과 같이 변경하십시오.
gawk 'xor(/\<foo\>/,/\<bar\>/)'
awk '((/(^|[^[:alnum:]_)foo([^[:alnum:]_]|$)/) + \
(/(^|[^[:alnum:]_)bar([^[:alnum:]_]|$)/)) % 2'
grep -P '^((?=.*\bfoo\b)(?!.*\bbar\b)|(?=.*\bbar\b)(?!.*\bfoo\b))'
들어 sed
그 당신이하지 않는 한 조금 복잡하게 sed
GNU처럼 구현을 sed
지원하는 \<
/ \>
GNU와 같은 단어 경계로 awk
한다.
답변
배쉬 솔루션 :
#!/bin/bash
while (( $# )); do
a=0 ; [[ $1 =~ foo ]] && a=1
b=0 ; [[ $1 =~ bar ]] && b=1
(( a ^ b )) && echo "$1"
shift
done
그것을 테스트하려면 :
$ ./script {foo,bar}\ {foo,bar} neither
foo foo
bar bar