Удаление строк на основе повторяющегося первого слова без учета регистра

У меня есть 1M векторов слов в формате fasttext (игнорируя первую строку, содержащую размер словаря и тусклость) . Каждая строка представляет собой слово, за которым следуют 300 чисел, разделенных пробелами, например.

      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 было бы хранить dict в нижнем регистре каждого слова и проверять слово каждой строки на этот dict, но мне любопытно решение awk / sed (или даже grep).

2 ответа

Решение

Использовать tolower($1) как ключ в массиве в awk.

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

С сортировкой GNU для -s для "стабильной сортировки" и при условии, что исходный порядок строк не нужно сохранять:

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

Разница между этим и awk-решением @Barmar заключается в следующем:

  1. Решение awk будет работать с любым awk, в то время как для сортировки требуется сортировка GNU для обеспечения печати первого дубликата.
  2. Решение awk сохранит порядок строк ввода, в то время как сортировка будет производить вывод в алфавитном порядке.
  3. Решение awk будет медленнее, чем решение sort.
  4. В решении awk не хватит памяти для меньших (но все же огромных) входных файлов, чем файл сортировки.
Другие вопросы по тегам