是否有一种从大文本文件中删除重复内容的简单方法?能够检测到重复的句子(用“。”分隔,甚至更好地找到句子片段的副本(例如4个字的文本片段)将会很棒。
答案 0 :(得分:2)
正如其他人所指出的那样,删除重复的单词很容易。比这更复杂的事情,你进入Natural Language Processing领域。 Bash不是最好的工具 - 你需要一个文明时代稍微优雅的武器。
我个人推荐Python,而NLTK(自然语言工具包)。在深入研究之前,可能值得一读NLP,以便您了解实际需要做什么。例如,文献中的“4字文本”被称为4克(在通用情况下为n-grams)。该工具包将帮助您找到这些,等等。
当然,可能有Python / NLTK的替代品,但我不熟悉。
答案 1 :(得分:1)
删除重复的短语并保留原始顺序:
nl -w 8 "$infile" | sort -k2 -u | sort -n | cut -f2
管道的第一个阶段在每行前面加上行号以记录原始订单。第二阶段使用唯一的开关集对原始数据进行排序。 第三个恢复原始顺序(排序1.列)。最终剪切删除了第一列。
答案 2 :(得分:0)
如果您首先uniq
文本文件,则可以删除与sort
重复的行(必须完全相等)。
$ cat foo.txt
foo
bar
quux
foo
baz
bar
$ sort foo.txt
bar
bar
baz
foo
foo
quux
$ sort foo.txt | uniq
bar
baz
foo
quux
除此之外,没有简单的方式来做你想做的事。 (你怎么会分开句子?)
答案 3 :(得分:0)
您可以将grep
与反向引用结合使用。
如果你写grep "\([[:alpha:]]*\)[[:space:]]*\1" -o <filename>
,它将匹配任何两个相同的单词。即如果文件内容为this is the the test file
,则会输出the the
。
(解释[[:alpha:]]
匹配任何字符az和AZ,星号*
后面意味着它可能会显示任意次数,\(\)
用于分组以反向引用它稍后,[[:space:]]*
匹配任意数量的空格和制表符,最后\1
匹配找到的确切序列,并附在\(\)
括号中
同样,如果你想匹配一组4个单词,连续两次重复,表达式将类似grep "\(\([[:alpha:]]*[[:space]]*\)\{4\}[[:space:]]*\1" -o <filename>
- 它将匹配例如a b c d a b c d
。 .*
。
现在我们需要在匹配之间添加任意字符序列。从理论上讲,这应该在反向引用之前插入grep "\(\([[:alpha:]]*[[:space]]*\)\{4\}.*\1" -o <filename>
,即{{1}},但这对我来说似乎不起作用 - 它只匹配任何字符串并忽略所说的反向引用
答案 4 :(得分:0)
简短的回答是没有简单的方法。通常,任何解决方案都需要首先决定如何将输入文档拆分成块(句子,每组4个单词等),然后比较它们以查找重复项。如果输出中非重复元素的排序与输入中的顺序非常重要,那么这只会使问题更加复杂。
最简单的bash友好解决方案是根据您选择的任何条件将输入拆分为行(例如,在每个.
上拆分,尽管安全地执行此引用有点棘手)然后使用标准副本检测机制(例如| uniq -c | sort -n | sed -E -ne '/^[[:space:]]+1/!{s/^[[:space:]]+[0-9]+ //;p;}'
然后,对于每个结果行,远程输入文本。
假设你有一个文件被正确地分成每个“句子”的行,那么
uniq -c lines_of_input_file | sort -n | sed -E -ne '/^[[:space:]]+1/!{s/^[[:space:]]+[0-9]+ //;p;}' | while IFS= read -r match ; do sed -i '' -e 's/'"$match"'//g' input_file ; done
可能就够了。当然,如果$match
包含sed
解释为模式的任何数据,它将会崩溃。如果这对您来说是个问题,则应采用另一种机制来执行实际替换。
注意:如果您使用的是GNU sed,则上面的-E
开关应更改为-r
答案 5 :(得分:0)
我刚刚在python中创建了一个脚本,它完全符合我最初的想法:
import string
import sys
def find_all(a_str, sub):
start = 0
while True:
start = a_str.find(sub, start)
if start == -1: return
yield start
start += len(sub)
if len(sys.argv) != 2:
sys.exit("Usage: find_duplicate_fragments.py some_textfile.txt")
file=sys.argv[1]
infile=open(file,"r")
text=infile.read()
text=text.replace('\n','') # remove newlines
table = string.maketrans("","")
text=text.translate(table, string.punctuation) # remove punctuation characters
text=text.translate(table, string.digits) # remove numbers
text=text.upper() # to uppercase
while text.find(" ")>-1:
text=text.replace(" "," ") # strip double-spaces
spaces=list(find_all(text," ")) # find all spaces
# scan through the whole text in packets of four words
# and check for multiple appearances.
for i in range(0,len(spaces)-4):
searchfor=text[spaces[i]+1:spaces[i+4]]
duplist=list(find_all(text[spaces[i+4]:len(text)],searchfor))
if len(duplist)>0:
print len(duplist),': ',searchfor
顺便说一句:我是一个蟒蛇新手,所以欢迎任何关于更好的蟒蛇练习的提示!