我有一个带有单词的纯文本文件,用逗号分隔,例如:
word1, word2, word3, word2, word4, word5, word 3, word6, word7, word3
我想删除重复项并成为:
word1, word2, word3, word4, word5, word6, word7
任何想法?我想,egrep可以帮助我,但我不确定,如何使用它......
答案 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命令。