Answers:
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'
具有(PCRE)grep支持-P:
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一样。