Wie kann man mit grep nach einer Zeile mit einem von zwei Wörtern suchen, aber nicht mit beiden?
11
Ich möchte in einer Textdatei nach Zeilen mit 'word1' XOR 'word2' suchen. Es sollte also Zeilen mit Wort1, Wort2 ausgeben, aber nicht die Zeilen mit diesen beiden Wörtern. Ich wollte das XOR verwenden, weiß aber nicht, wie ich das in der Linux-Befehlszeile schreiben soll.
grep 'word1\|word2' text.txtsucht nach Zeilen mit word1oder word2. Dies schließt Zeilen ein, die beide enthalten.
grep word1 text.txt | grep word2sucht nach Zeilen mit word1und word2. Die beiden Wörter können sich überschneiden (zB foobarenthält foound ob). Eine andere Möglichkeit, nach Zeilen zu suchen, die beide Wörter enthalten, jedoch nicht überlappend, besteht darin, sie in der folgenden Reihenfolge zu suchen:grep 'word1.*word2\|word2.*word1' text.txt
grep word1 text.txt | grep -v word2sucht nach Zeilen, die word1aber nicht enthalten word2. Die -vOption weist grep an, nicht übereinstimmende Zeilen beizubehalten und übereinstimmende Zeilen zu entfernen, anstatt das Gegenteil. Dies gibt Ihnen die Hälfte der gewünschten Ergebnisse. Durch Hinzufügen der symmetrischen Suche erhalten Sie alle Zeilen, die genau eines der Wörter enthalten.
Alternativ können Sie mit den Zeilen beginnen, die eines der beiden Wörter enthalten, und die Zeilen entfernen, die beide Wörter enthalten. Angesichts der obigen Bausteine ist dies einfach, wenn sich die Wörter nicht überschneiden.
Danke, genau das habe ich gesucht. Die anderen Antworten sind ebenfalls sehr interessant, also schauen Sie sie sich nicht an. Vielen Dank an alle für ihren Beitrag.
Wenn Sie nur ganze Wörter berücksichtigen möchten (die es weder foonoch barin foobaroder barbarzum Beispiel gibt), müssen Sie entscheiden, wie diese Wörter abgegrenzt werden. Wenn es sich um ein anderes Zeichen als Buchstaben, Ziffern und Unterstriche handelt, wie dies -wbei vielen grepImplementierungen der Fall ist, ändern Sie diese in:
Stephane, bitte schreibe ein Buch über Shell-Scripting!
Pfnuesel
Entschuldigung, ich habe erst vor ein paar Wochen mit der Kommandozeile begonnen. Wie würde ich es zwingen, nur nach Wörtern zu suchen? Ich habe -Pw und -wP ausprobiert, aber dies gab mir die falsche Ausgabe. Ich habe auch versucht, '' zwischen * word1 / * word2 und um word1 / word2 zu verwenden.
Lukali
@ Lukali, siehe bearbeiten.
Stéphane Chazelas
2
Eine Bash-Lösung:
#!/bin/bash
while (( $# )); do
a=0 ; [[ $1 =~ foo ]] && a=1
b=0 ; [[ $1 =~ bar ]] && b=1
(( a ^ b )) && echo "$1"
shift
done
Um es zu testen:
$ ./script {foo,bar}\ {foo,bar} neither
foo foo
bar bar
Mit GNU
awk
:Oder tragbar:
Mit einem
grep
mit Unterstützung für-P
(PCRE):Mit
sed
:Wenn Sie nur ganze Wörter berücksichtigen möchten (die es weder
foo
nochbar
infoobar
oderbarbar
zum Beispiel gibt), müssen Sie entscheiden, wie diese Wörter abgegrenzt werden. Wenn es sich um ein anderes Zeichen als Buchstaben, Ziffern und Unterstriche handelt, wie dies-w
bei vielengrep
Implementierungen der Fall ist, ändern Sie diese in:Dies
sed
wird etwas kompliziert, es sei denn, Sie haben einesed
Implementierung wie GNUsed
, die\<
/\>
als Wortgrenzen wie GNUawk
unterstützt.quelle
Eine Bash-Lösung:
Um es zu testen:
quelle