Удаление строк на основе повторяющегося первого слова без учета регистра
У меня есть 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 заключается в следующем:
- Решение awk будет работать с любым awk, в то время как для сортировки требуется сортировка GNU для обеспечения печати первого дубликата.
- Решение awk сохранит порядок строк ввода, в то время как сортировка будет производить вывод в алфавитном порядке.
- Решение awk будет медленнее, чем решение sort.
- В решении awk не хватит памяти для меньших (но все же огромных) входных файлов, чем файл сортировки.