grep
これら2つの単語のうちの1つだけが行に表示され、同じ行にある場合は、表示されていない2つの単語のうちの1つを含む行のみを表示したいと思います。
これまで試しましたが、 grep pattern1 | grep pattern2 | ...
期待した結果が得られませんでした。
答え1
それ以外の道具はgrep
行く道です。
たとえば、Perlを使用すると、コマンドは次のようになります。
perl -ne 'print if /pattern1/ xor /pattern2/'
perl -ne
stdin の各行に指定されたコマンドを実行します。この場合、一致する場合は行を印刷します。つまり、/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