如何使用grep搜索带有两个单词之一而不是两个单词的行?


11

我想在文本文件中搜索带有'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

还有更多,但没有成功。

Answers:


6

grep 'word1\|word2' text.txt搜索包含word1或的行word2。这包括包含两者的行。

grep word1 text.txt | grep word2搜索包含word1和的行word2。这两个词可以重叠(例如,foobar包含fooob)。搜索包含两个单词的行(但仅以非重叠方式)的另一种方法是按任一顺序搜索它们: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'

谢谢,这正是我一直在寻找的东西。其他答案也非常有趣,以至于病入膏look。谢谢大家的贡献。
卢卡利

17

使用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也不barfoobarbarbar为实例),你需要决定的那些话是如何界定。如果像-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一样。


6
Stephane,请写一本有关shell脚本的书!
pfnuesel

抱歉,我几周前才开始使用命令行。我将如何强迫它仅搜索单词?我尝试了-Pw和-wP,但这给了我错误的输出。我还尝试在* word1 / * word2和word1 / word2之间使用''。
卢卡利

@Lukali,请参阅编辑。
斯特凡Chazelas

2

一个bash解决方案:

#!/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
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.