我正在从文本中删除停用词,大致使用这个 代码
我有以下内容
$ cat file
file
types
extensions
$ cat stopwords
i
file
types
grep -vwFf stopwords file
我期待结果:
extensions
但我明白了(我认为不正确)
file
extensions
就好像该单词file
已在停用词文件中被跳过。现在很酷的一点是:如果我修改停用词文件,通过将i
第一行上的单个单词/字母更改为除f
, i
, l
,之外的任何其他 ascii 字母e
,那么相同的 grep 命令会给我一个不同且正确的结果extensions
。
这是怎么回事?我该如何解决?
我在 Mac OSX GNU bash 版本 4.4.12(1) 上使用 grep (BSD grep) 2.5.1-FreeBSD
答案1
这是 中的一个错误bsdgrep
,与跟踪当前行中仍要扫描的部分的变量有关,当涉及多个模式时,该变量会被对正则表达式匹配引擎的连续调用所覆盖。
本地修复
您可以在一定程度上解决此问题,方法是不使用该-w
选项,该选项依赖于此变量来进行正确操作,因此会失败,而是使用与单词开头和结尾匹配的正则表达式扩展,使您的stopwords
文件如下所示:
\<我\> \<文件\> \<类型\>
此解决方法还要求您不使用该-F
选项。
请注意,有记录的正则表达式组件[[:<:]]
以及[[:>:]]
手册re_format
告诉您的将不是在这里工作。这是因为编译的正则表达式库bsdgrep
打开了 GNU 正则表达式兼容性支持。这是另一个错误,据报道已修复。
服务修复
该错误已于今年早些时候修复。该修复尚未进入 FreeBSD 的 STABLE 或 RELEASE 版本,但据报道已在 CURRENT 中。
grep
要将其纳入源自 FreeBSD 的MacOS 版本bsdgrep
,请咨询 Apple。 ☺
进一步阅读
- 乔纳森·德·博因·波拉德 (2017-10-15)。当给定多个模式时,bsdgrep 的行为不正确。错误#223031。 FreeBSD Bugzilla。
- 凯尔·埃文斯(2017-04-03)。bsdgrep:修复匹配行为。修订版 316477。FreeBSD 源代码。
- 凯尔·埃文斯 (2017-05-02)。bsdgrep:修复 -w -v 与某些模式的匹配不正确 。修订版 317665。FreeBSD 源代码。
- 内森·威克斯 (2014-06-16)。grep(1) 和 bsdgrep(1) 无法识别 [[:<:]] 和 [[:>:]]。错误#191086。 FreeBSD Bugzilla。
答案2
这段代码:
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
产生:
-----
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
在这样的系统上:
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
有关 cgrep 的更多详细信息,可通过brew 和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)
干杯,drl