我有一个带有单词的纯文本文件,用逗号分隔,例如:
word1, word2, word3, word2, word4, word5, word 3, word6, word7, word3
我想删除重复项并成为:
word1, word2, word3, word4, word5, word6, word7
有任何想法吗?我认为, egrep 可以帮助我,但我不确定,如何准确地使用它......
我有一个带有单词的纯文本文件,用逗号分隔,例如:
word1, word2, word3, word2, word4, word5, word 3, word6, word7, word3
我想删除重复项并成为:
word1, word2, word3, word4, word5, word6, word7
有任何想法吗?我认为, egrep 可以帮助我,但我不确定,如何准确地使用它......
假设单词是每行一个,并且文件已经排序:
uniq filename
如果文件未排序:
sort filename | uniq
如果它们不是每行一个,并且您不介意它们是每行一个:
tr -s [:space:] \\n < filename | sort | uniq
但是,这并没有删除标点符号,所以也许你想要:
tr -s [:space:][:punct:] \\n < filename | sort | uniq
但这会从带连字符的单词中删除连字符。“man tr”获取更多选项。
ruby -pi.bak -e '$_.split(",").uniq.join(",")' filename
?
我承认这两种引用是丑陋的。
这是一个 awk 脚本,它将保留每一行,只删除重复的单词:
BEGIN {
FS=", "
}
{
for (i=1; i <= NF; i++)
used[$i] = 1
for (x in used)
printf "%s, ",x
printf "\n"
split("", used)
}
多亏了 ,创建一个唯一的列表非常容易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
我今天遇到了同样的问题.. 一个包含 238,000 个单词的单词列表,但其中大约 40,000 个是重复的。我已经通过这样做将它们放在单独的行中
cat filename | tr " " "\n" | sort
删除我只是做的重复项
cat filename | uniq > newfilename .
完美无误,现在我的文件从 1.45MB 减少到 1.01MB
我想你会想用换行符替换空格,使用uniq命令查找唯一行,然后再次用空格替换换行符。
我假设您希望单词在一行上是唯一的,而不是在整个文件中。如果是这种情况,那么下面的 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 (){}
循环之外。
在尝试解决几乎相同的问题时遇到了这个线程。我已经连接了几个包含密码的文件,所以自然有很多双打。此外,许多非标准字符。我真的不需要对它们进行排序,但似乎这对于 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 传递它,这样我才能看看我们是否得到了正确的输入。
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
它还保留了唯一不同是大小写的单词,这正是我想要的。我不需要对列表进行排序,所以它不是很好。
如果您也有兴趣计算单词数,请不要忘记实用程序的-c
选项。uniq
使用 vim ( ) 打开文件vim filename
并使用唯一标志 ( :sort u
) 运行排序命令。