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

问题描述 投票:19回答:10

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

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

我想删除重复项并成为:

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

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

linux file duplicates plaintext
10个回答
31
投票

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

uniq filename

如果文件未排序:

sort filename | uniq

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

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

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

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

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


0
投票

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


3
投票

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

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


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

2
投票

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

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

2
投票

我今天遇到了同样的问题..一个单词列表,有238,000个单词,但其中大约有40,000个是重复的。通过这样做,我已经把它们放在了各个方面

cat filename | tr " " "\n" | sort 

删除重复,我只是做了

cat filename | uniq > newfilename .

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


1
投票

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


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 (){}哈希。


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

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


0
投票

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

© www.soinside.com 2019 - 2024. All rights reserved.