编辑:我把这件事搞得太复杂了。这与反向 grep 无关。我仅使用 得到相同的结果grep -x -f stop.txt < in.txt
。如果在停用词文件中who
位于前面whose
,则结果只是who
.当停用词文件中的顺序相反时,in.txt
会找到 中的两行。我感觉我根本就不懂grep。
我无法让反向 grep 像我期望的那样工作,以便从文件中删除包含停用词的行。停用词的给出顺序会影响结果。
假设我有两个文件。输入文件in.txt
:
who
whose
以及一个包含停用词列表的文件stop.txt
:
who
whose
如果我in.txt
使用反向 grep 搜索对 中的停用词进行“过滤” stop.txt
,我会得到:
$ grep -vx -f stop.txt < in.txt
whose
$
仅当我更改stop.txt
为
whose
who
我得到:
$ grep -vx -f stop.txt < in.txt
$
我不明白为什么带有停用词的文件中的单词顺序很重要。
答案1
与模式文件
$ od -bc shortlong
0000000 167 150 157 012 167 150 157 163 145 012
w h o \n w h o s e \n
0000012
$ od -bc longshort
0000000 167 150 157 163 145 012 167 150 157 012
w h o s e \n w h o \n
0000012
我们可以测试一些变化,这里使用 macOS grep
(2.5.1-FreeBSD):
$ grep -x -f shortlong shortlong
who
$ grep -x -f shortlong longshort
who
$ grep -x -f longshort shortlong
who
whose
$ grep -x -f longshort longshort
whose
who
who
当第一个隐藏较长的whose
匹配项时。这似乎是一个错误。
仅当表达式来自文件时才会出现问题-f
,而不是当等效的(我们希望)表达式作为参数给出时:
$ grep -x -E 'who|whose' shortlong
who
whose
$ grep -x -E 'who|whose' longshort
whose
who
$ grep -x -E 'whose|who' shortlong
who
whose
$ grep -x -E 'whose|who' longshort
whose
who
GNU grep
(3.7) 不会出现此问题(grep
当前版本的 OpenBSD 也不会出现此问题):
$ ggrep -x -f shortlong shortlong
who
whose
$ ggrep -x -f shortlong longshort
whose
who
$ ggrep -x -f longshort shortlong
who
whose
$ ggrep -x -f longshort longshort
whose
who
因此,为避免此错误,请勿使用版本 2.5.1-FreeBSD,或者通过将非终极值替换为forgrep
来将正则表达式形成文件中的参数。\n
|
grep -E
$ paste -s -d \| shortlong
who|whose
$ grep -x -E -- "$(paste -s -d \| shortlong)" shortlong
who
whose
关于交替
理想情况下,在正则表达式替换中,较长的字符串应列在较短的字符串之前,除其他边缘情况外,这意味着人们应该更喜欢longshort
文件或whose|who
表格。
grep
出现(当它没有错误时)以得到正确的结果,但是其他正则表达式引擎将在第一个匹配处停止,如果您希望它们匹配,则必须首先列出最长的匹配:
$ printf 'who whoses the whosefolk' |
grep -o -E 'who|whose|whosefolk'
who
whose
whosefolk
$ printf 'who whoses the whosefolk' |
perl -nle 'print for /who|whose|whosefolk/g'
who
who
who
$ printf 'who whoses the whosefolk' |
perl -nle 'print for /whosefolk|whose|who/g'
who
whose
whosefolk