根据重复的第一个单词删除行,忽略大小写

Removing lines based on duplicate first word, ignoring case

我在 fasttext format (ignoring the first line containing vocab size and dim) 中有 1M 个词向量。每行是一个单词,后跟 300 个数字,全部 space 分隔,例如

Word 1.00 0.50 -2.30
WORD 0.90 0.40 -2.20

如何保留单词出现的第一行,忽略大小写,并删除所有其他行?例如,由于 Word 先出现,因此删除带有 WORD 的行,输出为

Word 1.00 0.50 -2.30

我可以使用 tr '[:upper:]' '[:lower:]' < wiki-news-300d-1M.vec 将所有单词转换为小写,但这会破坏单词的大小写。如果包含数字的整行匹配,我知道如何删除所有重复行,但这在这里没有用。我的 python 解决方案是保留一个字典存储每个单词的小写字母,并根据该字典检查每一行的单词,但我对 awk/sed(甚至 grep)解决方案感到好奇。

使用tolower()作为awk中数组的键。

awk '!a[tolower()]++' wiki-news-300d-1M.vec

使用 GNU 排序 -s 进行“稳定排序”并假设不需要保留原始行顺序:

$ sort -k1,1 -fsu file
Word 1.00 0.50 -2.30

这个和的区别是:

  1. awk 解决方案将使用任何 awk 工作,而排序解决方案需要 GNU 排序以确保打印第一个副本。
  2. awk 解决方案将保留输入行顺序,而排序解决方案将按字母顺序生成输出。
  3. awk 解决方案会比 sort 解决方案慢。
  4. awk 解决方案将 运行 对于比排序文件更小(但仍然很大)的输入文件内存不足。