如何使用linux命令从纯文本文件中删除重复的单词

时间:2009-06-04 18:24:38

标签: linux file duplicates plaintext

我有一个带有单词的纯文本文件,用逗号分隔,例如:

word1, word2, word3, word2, word4, word5, word 3, word6, word7, word3

我想删除重复项并成为:

word1, word2, word3, word4, word5, word6, word7

任何想法?我想,egrep可以帮助我,但我不确定,如何使用它......

10 个答案:

答案 0 :(得分:31)

假设单词是每行一个,并且文件已经排序:

uniq filename

如果文件未排序:

sort filename | uniq

如果他们不是每行一个,你不介意他们每行一个:

tr -s [:space:] \\n < filename | sort | uniq

但这并不能删除标点符号,所以也许你想要:

tr -s [:space:][:punct:] \\n < filename | sort | uniq

但是这会删除带连字符的连字符。 “man tr”有更多选择。

答案 1 :(得分:3)

ruby -pi.bak -e '$_.split(",").uniq.join(",")' filename

我承认这两种语录很难看。

答案 2 :(得分:2)

由于uniq,创建一个唯一的列表非常简单,尽管大多数Unix命令如每行一个条目而不是逗号分隔列表,所以我们必须先将其转换为:

$ sed 's/, /\n/g' filename | sort | uniq
word1
word2
word3
word4
word5
word6
word7

更难的部分是将它再次放在一行,逗号分隔符而不是终结符。我使用了perl one-liner来做到这一点,但如果有人有更多惯用的东西,请编辑我。 :)

$ sed 's/, /\n/g' filename | sort | uniq | perl -e '@a = <>; chomp @a; print((join ", ", @a), "\n")'
word1, word2, word3, word4, word5, word6, word7

答案 3 :(得分:2)

这是一个awk脚本,它将使每一行保持完好,只删除重复的单词:

BEGIN { 
     FS=", " 
} 
{ 
    for (i=1; i <= NF; i++) 
        used[$i] = 1
    for (x in used)
        printf "%s, ",x
    printf "\n"
    split("", used)
} 

答案 4 :(得分:2)

我今天遇到了同样的问题..一个包含238,000个单词的单词列表,但其中大约有40,000个是重复的。我已经通过

将它们分成了各个行
cat filename | tr " " "\n" | sort 

删除我刚才做的重复

cat filename | uniq > newfilename .

完美没有错误,现在我的文件从1.45MB下降到1.01MB

答案 5 :(得分:1)

我认为你想要用换行符替换空格,使用uniq命令查找唯一的行,然后再用空格替换换行符。

答案 6 :(得分:1)

我认为你希望单词在一行中是唯一的,而不是整个文件。如果是这种情况,那么下面的Perl脚本就可以了。

while (<DATA>)
{
    chomp;
    my %seen = ();
    my @words = split(m!,\s*!);
    @words = grep { $seen{$_} ? 0 : ($seen{$_} = 1) } @words;
    print join(", ", @words), "\n";
}

__DATA__
word1, word2, word3, word2, word4, word5, word3, word6, word7, word3

如果您希望整个文件具有唯一性,则可以将%seen哈希移到while (){}循环之外。

答案 7 :(得分:1)

在尝试解决同样的问题时遇到了这个问题。我已经连接了几个包含密码的文件,所以自然会有很多双打。还有很多非标准字符。我并不是真的需要它们排序,但似乎这对uniq来说是必要的。

我试过了:

sort /Users/me/Documents/file.txt | uniq -u
sort: string comparison failed: Illegal byte sequence
sort: Set LC_ALL='C' to work around the problem.
sort: The strings compared were `t\203tonnement' and `t\203tonner'

尝试:

sort -u /Users/me/Documents/file.txt >> /Users/me/Documents/file2.txt
sort: string comparison failed: Illegal byte sequence
sort: Set LC_ALL='C' to work around the problem.
sort: The strings compared were `t\203tonnement' and `t\203tonner'.

甚至尝试先将它传递给猫,这样我才能看到我们是否得到了正确的输入。

cat /Users/me/Documents/file.txt | sort | uniq -u > /Users/me/Documents/file2.txt
sort: string comparison failed: Illegal byte sequence
sort: Set LC_ALL='C' to work around the problem.
sort: The strings compared were `zon\351s' and `zoologie'.

我不确定发生了什么。字符串“t \ 203tonnement”和“t \ 203tonner”在文件中找不到,但是找到“t / 203”和“tonnement”,但是在单独的非相邻行上。与“zon \ 351s”相同。

最终对我有用的是:

awk '!x[$0]++' /Users/me/Documents/file.txt > /Users/me/Documents/file2.txt

它还保留了唯一不同的词语,这就是我想要的。我不需要对列表进行排序,所以很好,但事实并非如此。

答案 8 :(得分:0)

如果您对计算单词的数量感兴趣,请不要忘记-c实用程序的uniq选项。

答案 9 :(得分:0)

使用vim(vim filename)打开文件并使用唯一标记(:sort u)运行sort命令。