grep seltsames Verhalten mit Einzelbuchstaben

10

Ich entferne Stoppwörter aus einem Text und verwende ungefähr diesen Code

Ich habe folgendes

$ cat file
file
types
extensions

$ cat stopwords
i
file
types

grep -vwFf stopwords file

Ich erwarte das Ergebnis: extensions

aber ich bekomme das (ich denke falsch)

file
extensions

Es ist, als ob das Wort filein der Stoppwortdatei übersprungen wurde. Jetzt ist hier das kühle Bit: wenn ich die Stoppwörter - Datei ändern, indem Sie das Wort / den Wechsel iin der ersten Zeile, jeden anderen ascii Brief abgesehen von f, i, l, e, dann wird der gleiche Befehl grep gibt mir ein anderes und korrektes Ergebnis extensions.

Was ist hier los und wie behebe ich das?

Ich verwende grep (BSD grep) 2.5.1-FreeBSD auf einer Mac OSX GNU-Bash, Version 4.4.12 (1).

Tim
quelle
Möglicherweise möchten Sie den -xSchalter für Zeilenregex anstelle von -wWort verwenden? Ich denke jedoch, dass der -FSchalter einen von ihnen aufheben wird oder umgekehrt.
Jesse_b
grep (GNU grep) 3.1 funktioniert wie erwartet.
Hauke ​​Laging
Ich habe das wiederholt. Ein weiteres Datum: Wenn Sie das iMuster zum zweiten und nicht zum ersten Muster in der stopwordsDatei machen, ändert sich auch das Verhalten.
JdeBP
Ich kann das Verhalten unter OpenBSD 6.2 grepweder mit Native noch mit GNU grep3.1 reproduzieren .
Kusalananda

Antworten:

13

Dies war ein Fehler in bsdgrepBezug auf eine Variable, die den noch zu scannenden Teil der aktuellen Zeile verfolgt, der mit aufeinanderfolgenden Aufrufen der Matching-Engine für reguläre Ausdrücke überschrieben wird, wenn mehrere Muster beteiligt sind.

lokaler Fix

Sie können dies bis zu einem gewissen Grad umgehen, indem Sie nicht die -wOption verwenden, die für eine korrekte Operation auf dieser Variablen beruht und daher fehlschlägt, sondern stattdessen die Erweiterungen für reguläre Ausdrücke verwenden, die mit dem Anfang und dem Ende von Wörtern übereinstimmen, sodass Ihre stopwordsDatei wie folgt aussieht:

\ <i \>
\ <Datei \>
\ <Typen \>

Diese Problemumgehung erfordert auch, dass Sie die -FOption nicht verwenden .

Beachten Sie, dass die dokumentierten Komponenten für reguläre Ausdrücke [[:<:]]und [[:>:]]das re_formatHandbuch, über das Sie informiert werden, hier nicht funktionieren. Dies liegt daran, dass in der Bibliothek für reguläre Ausdrücke, in die kompiliert wird, die bsdgrepKompatibilitätsunterstützung für reguläre Ausdrücke von GNU aktiviert ist. Dies ist ein weiterer Fehler, der angeblich behoben ist.

Service-Fix

Dieser Fehler wurde Anfang dieses Jahres behoben. Das Update hat es noch nicht in die STABLE- oder RELEASE-Varianten von FreeBSD geschafft, ist aber Berichten zufolge in CURRENT.

Wenden Sie sich an Apple, um dies in die MacOS-Version von zu integrieren grep, die von FreeBSDs abgeleitet ist bsdgrep. ☺

Weiterführende Literatur

JdeBP
quelle
Schön, und danke, dass du dies vorgelagert hast. Ich würde diese Antwort noch faszinierender finden, wenn sie den Buggy-Code zitieren würde.
Dhag
1

Dieser Code:

pl " Input data file data1 and stopwords file data2:"
head data1 data2

pl " Expected output:"
cat $E

pl " Results, grep:"
# grep -vwFf stopwords file
grep -vwFf data2 data1

pl " Results, cgrep:"
cgrep -x1 -vFf data2 data1

produziert:

-----
 Input data file data1 and stopwords file data2:
==> data1 <==
file
types
extensions

==> data2 <==
i
file
types

-----
 Expected output:
extensions

-----
 Results, grep:
file
extensions

-----
 Results, cgrep:
extensions

Auf einem System wie:

OS, ker|rel, machine: Apple/BSD, Darwin 16.7.0, x86_64
Distribution        : macOS 10.12.6 (16G29), Sierra
bash GNU bash 3.2.57

Weitere Details zu cgrep, erhältlich über Brew und von SourceForge:

cgrep   shows context of matching patterns found in files (man)
Path    : ~/executable/cgrep
Version : 8.15
Type    : Mach-O64-bitexecutablex86_64 ...)
Home    : http://sourceforge.net/projects/cgrep/ (doc)

Prost, drl

drl
quelle
habe mir gerade einen neuen grep besorgt.
Tim
@ Tim - Ich hoffe, Sie finden cgrep so nützlich wie ich. Die Geschwindigkeit der Tests, die ich durchgeführt habe, entspricht in etwa der von GNU grep, und die Funktionen "Kontext / Fenster" sind sehr nützlich. Es baut auch leicht auf Linux-Systemen auf ... Prost, drl
drl