У меня есть большой файл, содержащий одну строку в каждой строке. Я хотел бы иметь возможность быстро определить, есть ли строка в файле. В идеале это должно быть сделано с использованием алгоритма двоичного типа.
Некоторые Googling показали look
команду с -b
флагом, который обещает найти и вывести все строки, начиная с заданного префикса, используя алгоритм двоичного поиска. К сожалению, он не работает должным образом и возвращает нулевые результаты для строк, которые, как я знаю, находятся в файле (они правильно возвращаются при эквивалентном grep
поиске).
Кто-нибудь знает другую утилиту или стратегию для эффективного поиска этого файла?
look
команда работала правильно, потому что внешний вид, похоже, игнорирует локаль и просто использует C, как сортировку жестко, я также открыл ошибку из-за этого запутанного поведения: bugzilla.kernel.org/show_bug.cgi?id=198011look -b
не удалось для меня с ошибкойFile too large
. Я думаю, что он пытается прочитать все это в памяти.Ответы:
Есть существенная разница между
grep
иlook
:Если явно не указано иное,
grep
шаблоны будут найдены даже где-то внутри строк. Дляlook
man-страницы говорится:Я пользуюсь не
look
очень часто, но на тривиальном примере, который я только что попробовал, он работал нормально.источник
egrep "^TEST" sortedlist.txt | wc -l
я получу 41 289 результатов. Однако эквивалентныеlook
команды,look -b TEST sortedlist.txt | wc -l
дают только результаты 1995 года. Мне почти интересно, есть ли ошибка вlook
.look
использует другие параметры сортировки, чем программа, которую вы использовали для сортировки файла.Может быть, немного поздно ответ:
Сгреп вам поможет.
Sgrep (сортированный grep) ищет в отсортированных входных файлах строки, соответствующие ключу поиска, и выводит соответствующие строки. При поиске больших файлов sgrep работает намного быстрее, чем традиционный Unix grep, но со значительными ограничениями.
Вы можете скачать источник здесь: https://sourceforge.net/projects/sgrep/?source=typ_redirect
и документы здесь: http://sgrep.sourceforge.net/
Другой путь:
Я не знаю, насколько большой файл. Может быть, вы должны попробовать параллельно:
/programming/9066609/fastest-possible-grep
Я всегда делаю grep с файлами, размер которых> 100 ГБ, это работает хорошо.
источник
sudo apt-get install sgrep
чтобы получить sgrep, sgrep в репозиториях Buntu на самом деле не является этим sgrep, я не уверен, что это то же самое.Вы можете хэшировать файл на части, а затем извлекать нужный фрагмент:
тогда поиск будет выглядеть так:
Это делает две вещи:
источник
sgrep может работать на вас:
На странице проекта http://sgrep.sourceforge.net/ написано:
Однако для вставки, я думаю, нет лучшего решения, чем использование базы данных: /programming/10658380/shell-one-liner-to-add-a-line-to-a-sorted-file/ 33859372 # 33859372
источник
sgrep
самом деле в репозиториях Ubuntu есть этот sgrep , который предназначен для «поиска файла по структурированному шаблону» и не имеет ничего общего с бинарным поиском.Если вы хотите, чтобы это действительно быстро (O (1) быстро), вы можете создать хэш-набор для изучения. Я не смог найти реализацию, которая позволила бы мне сохранить в файле предварительно созданный хэш-набор и проверить его, не считывая весь файл в память, поэтому я свернул свой собственный .
Создайте хэш-набор (
-b
/--build
):Зонд хэш-набора (
-p
/--probe
):... или со строкой для поиска на стандартном вводе:
Вы можете отключить вывод
--probe
с помощью параметра-q
/,--quiet
если вас интересует только состояние выхода:Дополнительные параметры см. В описании использования, доступном через параметр
-h
/--help
или сопровождающийREADME
файл.источник