更新:澄清行号要求,减少一些冗长的内容
从命令行,有没有办法:
- 检查英文文本文件
- 查找重复单词的拼写错误,
- 以及找到它们的行号,
以帮助纠正它们?
实施例1
目前,帮助完成一篇文章或其他英语写作,aspell -c text.txt
有助于发现拼写错误。但是,当错误是无意中连续重复某个单词时,就没有帮助了。
highlander_typo.txt
:
There can be only one one.
跑步aspell
:
$ aspell -c highlander_typo.txt
可能因为aspell
是拼写检查器,而不是语法检查器,所以重复单词拼写错误超出了其预期的功能范围。因此,结果是该文件通过了aspell
检查,因为就单个单词拼写而言没有任何“错误”。
正确的句子是There can be only one.
,第二个one
是无意的重复单词拼写错误。
实施例2
但另一种情况是例如kylie_minogue.txt
:
La la la
这里的重复不是打字错误,因为这些是艺术家的一部分歌曲歌词。
因此,解决方案不应自行假设和“修复”任何内容,否则它可能会覆盖故意重复的单词。
示例 3:多行
jefferson_typo.txt
:
He has has refused his Assent to Laws, the most wholesome and necessary
for the public good.
He has forbidden his Governors to pass Laws of immediate and
and pressing importance, unless suspended in their operation till his
Assent should be be obtained; and when so suspended, he has utterly
neglected to attend to them.
修改自独立宣言
在上面的六行中,
- 1:
He has has refused
应该是He has refused
,第二个has
是重复单词拼写错误 - 5:
should be be obtained
应该是should be obtained
,第二个be
是重复单词拼写错误
但是,您是否注意到第三个重复单词拼写错误?
- 3:
... immediate and
- 4:
and pressing ...
这也是一个重复单词拼写错误,因为尽管它们位于不同的行上,但它们仍然是同一个英语句子的一部分,但上行的尾部有一个单词被意外添加到下一行的开头。由于重复出现在一段文本的两侧,因此用肉眼很难察觉。
预期输出
一个交互式程序,其过程类似于
aspell -c
但能够检测重复单词,或者,能够提取行号和可疑重复单词的脚本或命令组合。此信息使使用编辑器变得更容易,例如
vim
跳转到重复单词并在适当的情况下进行修复。
使用上面的 multi-line jefferson_typo.txt
,所需的输出将类似于:
1: has has
3: and
4: and
5: be be
或者:
1: He [has has] refused his Assent to Laws, the most wholesome and necessary
3: He has forbidden his Governors to pass Laws of immediate [and]
4: [and] pressing importance, unless suspended in their operation till his
5: Assent should [be be] obtained; and when so suspended, he has utterly
实际上,我并不完全确定如何显示行间或跨行重复单词的困难情况,例如and
上面的重复,所以如果您的解决方案与此不完全相似,请不要担心。
但我希望,就像上面所说的那样,它表明:
- 相关原始输入的行号
- 某种方式来引起人们对重复内容的注意,如果文本行也很长,则特别有用。
- 如果显示整行来提供上下文(来源:@Wildcard),那么需要有一种方法以某种方式以独特的方式呈现重复的单词。此处显示的示例通过将重复包含在 ASCII 字符内来标记重复
[
]
。或者,也许模仿grep --colors=always
对线的匹配进行着色以在彩色终端中显示
其他考虑因素
- 文本,应保留为纯文本文件
- 请不要提供 GUI 解决方案,仅提供文本解决方案。
ssh -X
X11 转发不可靠,需要重新编辑ssh
失败的尝试
我想到了要尝试找到重复项uniq
,因此计划首先确定如何让重复单词识别在单行上工作。
为了使用,uniq
我们需要首先将一行上的单词转换为每行一个单词。
$ tr ' ' '\n' < highlander_typo.txt
There
can
be
only
one
one.
很遗憾:
$ tr ' ' '\n' < highlander_typo.txt | uniq -D
没有什么。
这是因为对于-D
通常会显示重复项的选项,输入必须完全是重复行。不幸的是,.
重复单词末尾的句号one
否定了这一点。它只是看起来像一条不同的线。不确定我将如何解决任意标点符号(例如这个句号),并在tr
处理后以某种方式将其添加回来。
这是不成功的。但如果成功,接下来需要有一种方法来包含该行的行号,因为输入文件可能有数百行,这将有助于指示输入文件的哪一行检测到重复单词在。
这种单行代码处理可能是父循环的一部分,以便进行某种逐行多行处理,从而能够处理文件中的所有行,但不幸的是甚至超越了单行重复单词识别一直是个问题。
答案1
编辑:添加了安装和演示
您至少需要处理一些边缘情况,例如
- 在行的末尾(和开头)重复单词。
- 搜索应该不区分大小写,因为经常出现
The the apple
. - 也许您只想将搜索限制为单词组成部分,以不匹配类似
( ( a + b) + c )
(重复左括号。 - 只有完整的单词才能匹配以消除
the thesis
- 当涉及到人类语言时,应该正确解释单词中的 Unicode 字符
总而言之,我推荐pcregrep
解决方案:
pcregrep -Min --color=auto '\b([^[:space:]]+)[[:space:]]+\1\b' file
显然,颜色和行号(n
选项)是可选的,但通常很好。
安装
在基于 Debian 的发行版上,您可以通过以下方式安装:
$ sudo apt-get install pcregrep
例子
运行命令jefferson_typo.txt
即可查看:
$ pcregrep -Min --color=auto '\b([^[:space:]]+)[[:space:]]+\1\b' jefferson_typo.txt
1:He has has refused his Assent to Laws, the most wholesome and necessary
3:He has forbidden his Governors to pass Laws of immediate and
and pressing importance, unless suspended in their operation till his
5:Assent should be be obtained; and when so suspended, he has utterly
上面只是一个文本捕获,但在支持颜色的终端上,匹配项是彩色的:
- 有 有
- 和
- 和
- 是 是
答案2
这将打印包含重复单词的行(带有文件名和行号):
for f in *.txt; do
perl -ne 'print "$ARGV: $.: $_" if /\b(\w+)\W+\1/' "$f"
done
对于多行匹配,有这个,但是您会丢失行号,因为它是按段落在文件中吸食的(这就是该-00
选项的效果)。两个单词之间的\W+
表示任何“非单词”字符,包括换行符。
perl -00 -nE '
@matches = /\b((\w+)\W+\2)/g;
while (@matches) {
($match,$word) = splice @matches, 0, 2;
say "dup: $match";
}
' jefferson_typo.txt
dup: has has
dup: and
and
dup: be be
答案3
你应该看看可敬的人diction(1)
和style(1)
命令。他们捕捉到各种各样的嘘声。有新版本(Fedora 23 上的 GPLv3)。
安装
例如,在基于 Debian 的发行版上,安装软件包diction
,其中包括style
:
$ sudo apt-get install diction
至少在 Fedora 中是这样的:
$ dnf install diction
红帽企业版(和克隆版)可能需要:
$ yum install diction
无论如何,这来自上游 GNU 包,名为diction
,所以它几乎在任何地方都应该被称为相同的。
例子
$ diction jefferson_typo.txt
jefferson_typo.txt:1: He has [has] refused his Assent to Laws, the [most] wholesome and necessary for the public good.
jefferson_typo.txt:3: He has forbidden his Governors to pass Laws of immediate and [and] pressing importance, unless suspended in their operation till his Assent should be [be] obtained; and when [so] suspended, he has utterly neglected to attend to them.
2 phrases in 2 sentences found.
优点
- 除其他外,捕捉重复的单词
缺点
- 引入
[]
与重复单词无关的项目的标记。例如[so]
,可能被标记,因为它可以被认为是无关的斯特伦克的《风格元素》。看man diction
- 显示的数字并不总是原始输入的行号,而是句子开始的行号。例如,
[be]
原始输入的行号是 5,但这里它3
仅显示because[be]
是从 line 开始的句子的一部分3
。所以这与你想要的略有不同
答案4
既然您用 标记了这个问题awk
,为什么不直接使用 呢awk
?
$ awk '
BEGIN{RS=FS="\\W+"}
$0==t{printf("%s:%s\t%s %s\n", FILENAME, FNR, t, $0)}
{t=$0}
' *.txt
highlander_typo.txt:6 one one
jefferson_typo.txt:3 has has
jefferson_typo.txt:29 and and
jefferson_typo.txt:42 be be
kylie_minogue.txt:3 la la
我没有保留换行符,jefferson_typo.txt
因为它在视觉上对我没有帮助,但你可以根据你的口味进行调整。