Найти нужные строки во множестве документов
Модераторы: /dev/random, Модераторы разделов
-
- Сообщения: 4
Найти нужные строки во множестве документов
Товарищи, подскажите
Имеется несколько сотен гигабайт текстовых документов .txt лежащих в папках и подпапках. В этих документах в столбик записаны имя и фамилия различных людей типа
Василий Иванов
Николай Петров
Федор Зорин
Максим Котов
Николай Белов
Максим Матов
...
Помогите составить команду которая найдет во всех вложеных папках во всех этих сотнях гигабайт текстовых документов только строки содержащие нужные имена, например, только строки с "Василий", "Николай", "Максим" и составит из этих строк новый файл .txt
ПС. Может есть лучший способ как выполнить эту задачу максимально быстро с учетом многогигабайтности данных?
Имеется несколько сотен гигабайт текстовых документов .txt лежащих в папках и подпапках. В этих документах в столбик записаны имя и фамилия различных людей типа
Василий Иванов
Николай Петров
Федор Зорин
Максим Котов
Николай Белов
Максим Матов
...
Помогите составить команду которая найдет во всех вложеных папках во всех этих сотнях гигабайт текстовых документов только строки содержащие нужные имена, например, только строки с "Василий", "Николай", "Максим" и составит из этих строк новый файл .txt
ПС. Может есть лучший способ как выполнить эту задачу максимально быстро с учетом многогигабайтности данных?
-
- Сообщения: 3729
- Статус: Многоуважаемый джинн...
- ОС: Slackware64-14.1/14.2
Re: Найти нужные строки во множестве документов
Навскидку как-то так:
Создаем текстовый файл с ключами поиска (по одному ключу на строку)
patterns.txt
Поиск по различным файлам:
find -name "*.txt" -exec grep -f patterns.txt '{}' \; >>newfile.txt
Насколько это будет (не)быстро, судить не берусь, решение, можно сказать, "в лоб".
Сам таким иногда пользуюсь, но у меня объемы поиска существенно меньше.
Нужно ещё учесть кодировку файлов.
И не плохо бы, чтобы искомые файлы/каталоги имели хоть какой-то общий корень, если такой есть, тогда поиск начинать оттуда,
иначе много лишних файлов придется просматривать и это может дать побочные результаты.
Если же есть возможность составить список просматриваемых файлов (с полными путями),
то можно натравить grep конкретно на файлы из этого списка, что исключит ложные срабатывания.
Создаем текстовый файл с ключами поиска (по одному ключу на строку)
patterns.txt
Код: Выделить всё
Василий
Николай
Максим
find -name "*.txt" -exec grep -f patterns.txt '{}' \; >>newfile.txt
Насколько это будет (не)быстро, судить не берусь, решение, можно сказать, "в лоб".
Сам таким иногда пользуюсь, но у меня объемы поиска существенно меньше.
Нужно ещё учесть кодировку файлов.
И не плохо бы, чтобы искомые файлы/каталоги имели хоть какой-то общий корень, если такой есть, тогда поиск начинать оттуда,
иначе много лишних файлов придется просматривать и это может дать побочные результаты.
Если же есть возможность составить список просматриваемых файлов (с полными путями),
то можно натравить grep конкретно на файлы из этого списка, что исключит ложные срабатывания.
-
- Сообщения: 873
- ОС: debian, fedora (i3-wm)
Re: Найти нужные строки во множестве документов
В grep есть опция -r и --include=\*.txtHephaestus писал: ↑20.10.2020 14:03find -name "*.txt" -exec grep -f patterns.txt '{}' \; >>newfile.txt
-
- Модератор
- Сообщения: 20348
- Статус: nulla salus bello
- ОС: Debian GNU/Linux
Re: Найти нужные строки во множестве документов
Это неэффективно. Нужно заякорить:Hephaestus писал: ↑20.10.2020 14:03Создаем текстовый файл с ключами поиска (по одному ключу на строку)
patterns.txtКод: Выделить всё
Василий Николай Максим
Код: Выделить всё
^Василий
^Николай
^Максим
Пишите правильно:
в консоли вку́пе (с чем-либо) в общем вообще | в течение (часа) новичок нюанс по умолчанию | приемлемо проблема пробовать трафик |
-
- Сообщения: 3729
- Статус: Многоуважаемый джинн...
- ОС: Slackware64-14.1/14.2
Re: Найти нужные строки во множестве документов
Вообще, это зависит от исходных файлов.Bizdelnick писал: ↑20.10.2020 15:33Это неэффективно. Нужно заякорить:Код: Выделить всё
^Василий ^Николай ^Максим
Если там строки типа
Код: Выделить всё
Василий Иванов
Николай Петров
Но если вдруг будет
Код: Выделить всё
Иванов Василий Петрович
Петров Николай Семенович
тогда строки нужно обрамлять пробелами:
Код: Выделить всё
Василий
Николай
Максим
В любом случае, я показал лишь идею. Понятно, что итоговый вариант будет отличаться.
В данной конкретной задаче так, наверное, лучше. Вывод grep с подсветкой получится.
А в общем случае у find возможностей отбора побольше будет.
Я эту самую опцию --include у grep даже когда-то пробовал, кажется, но как-то не прижилась. Уже не помню, почему.
-
- Модератор
- Сообщения: 20348
- Статус: nulla salus bello
- ОС: Debian GNU/Linux
Re: Найти нужные строки во множестве документов
Я исхожу из того, что они такие, как описал ТС.
Пишите правильно:
в консоли вку́пе (с чем-либо) в общем вообще | в течение (часа) новичок нюанс по умолчанию | приемлемо проблема пробовать трафик |
-
- Сообщения: 873
- ОС: debian, fedora (i3-wm)
Re: Найти нужные строки во множестве документов
Может скушать много ресурсов и подвесить соседей, есть такое.
Добавлено (19:19):
Это я о рекурсивной опции со множеством сложных паттернов. Через find будет с любыми вариантами плавнее-
- Сообщения: 1139
- ОС: Fedora
Re: Найти нужные строки во множестве документов
только задача какая-то странная. Что, в файлах только имена, а поиск не требуется морфологический? Ну, нашлось — что дальше нужно?
-
- Сообщения: 4
Re: Найти нужные строки во множестве документов
Спасибо!
Мне тут подсказали, что на больших объемах для ускорения можно использовать другие утилиты, в частности ag (Silver Searcher). Будет гораздо быстрее.
https://beyondgrep.com/feature-comparison/
Кого лучше? И как запрос будет выглядеть тогда?
Мне тут подсказали, что на больших объемах для ускорения можно использовать другие утилиты, в частности ag (Silver Searcher). Будет гораздо быстрее.
https://beyondgrep.com/feature-comparison/
Кого лучше? И как запрос будет выглядеть тогда?
-
- Модератор
- Сообщения: 20348
- Статус: nulla salus bello
- ОС: Debian GNU/Linux
Re: Найти нужные строки во множестве документов
Вряд ли будет большая разница, в любом случае упрётесь в скорость чтения с диска. Впрочем, можете поэкспериментировать.
Регулярки будут выглядеть точно так же в любом синтаксисе. Что basic, что extended, что perl.
Пишите правильно:
в консоли вку́пе (с чем-либо) в общем вообще | в течение (часа) новичок нюанс по умолчанию | приемлемо проблема пробовать трафик |
-
- Сообщения: 2477
- ОС: Gentoo
Re: Найти нужные строки во множестве документов
codesearch в помощь.
Просто проиндексировать каталог с файлами(cindex), и выполнить поиск(csearch).
Для Gentoo писал когда то ебилд, для тестовой ветки с гита, теперь добавил ебилд для версии 1.2.0.
Просто проиндексировать каталог с файлами(cindex), и выполнить поиск(csearch).
Для Gentoo писал когда то ебилд, для тестовой ветки с гита, теперь добавил ебилд для версии 1.2.0.
-
- Сообщения: 1179
- ОС: Slackware
Re: Найти нужные строки во множестве документов
А с помощью awk данную задачу не решить? Я просто про bash читаю, там оно как раз для работы с файлами предлагается.
"Однажды один очень мудрый человек… ничего не сказал. Времена были опасные, да и собеседники ненадёжные"
-
- Сообщения: 2477
- ОС: Gentoo
-
- Модератор
- Сообщения: 20348
- Статус: nulla salus bello
- ОС: Debian GNU/Linux
Re: Найти нужные строки во множестве документов
Чем лучше и почему быстрее?
Пишите правильно:
в консоли вку́пе (с чем-либо) в общем вообще | в течение (часа) новичок нюанс по умолчанию | приемлемо проблема пробовать трафик |
-
- Сообщения: 2477
- ОС: Gentoo
Re: Найти нужные строки во множестве документов
Оно вообще отрабатывает быстрее чем grep, ну и может вывести просто список файлов в которых присутствует указанное слово, что делает очень удобным в скриптах:
Shell
$ rg -t txt --files-with-matches PATTERN
Shell
$ rg -NI -j4 -t txt PATTERN /PATH >file.txt
-
- Модератор
- Сообщения: 20348
- Статус: nulla salus bello
- ОС: Debian GNU/Linux
Re: Найти нужные строки во множестве документов
Быстрее читает файлы с диска?
Программа не может работать «вообще быстрее», время выполнения зависит от массы факторов. Она может быстрее компилировать регулярки, но при этом они будут медленнее работать, или наоборот. Может работать быстрее с простыми регулярками, но тормозить со сложными, или наоборот. Скорость может зависеть от размера файлов, объёма ОЗУ, кешей процессора, ещё кучи факторов. Короче, без теста в конкретных условиях такие заявления совершенно безосновательны.
И зачем это надо в данном случае?
Добавлено (22:17):
С grep -R тоже достаточно одной команды.
Вот вообще не факт, что выполнение в несколько потоков не замедлит работу вместо того, чтобы ускорить, если файлы читаются с HDD. Будут только головку туда-сюда перепозиционировать.
Пишите правильно:
в консоли вку́пе (с чем-либо) в общем вообще | в течение (часа) новичок нюанс по умолчанию | приемлемо проблема пробовать трафик |
-
- Сообщения: 2477
- ОС: Gentoo
Re: Найти нужные строки во множестве документов
Кто знает, вот попробовал несколько раз запустить:Bizdelnick писал: ↑06.11.2020 22:15Вот вообще не факт, что выполнение в несколько потоков не замедлит работу вместо того, чтобы ускорить, если файлы читаются с HDD. Будут только головку туда-сюда перепозиционировать.
Spoiler
Shell
$ time grep -Rh --include=\*.txt word program/ >/dev/null
real 0m0,174s
user 0m0,105s
sys 0m0,069s
$ time rg -NI -j4 -t txt word program/>/dev/null
real 0m0,087s
user 0m0,223s
sys 0m0,048s
$ time grep -Rh --include=\*.txt word program/ >/dev/null
real 0m0,128s
user 0m0,068s
sys 0m0,060s
$ time rg -NI -j4 -t txt word program/>/dev/null
real 0m0,083s
user 0m0,207s
sys 0m0,064s
Вот поробовал специально первый поиск grep и rg в каталоге /usr/include(кеширования ещё небыло):
Spoiler
Shell
$ time grep -Rh include /usr/include/ >/dev/null
real 0m19,676s
user 0m0,531s
sys 0m3,188s
$ time rg -NI -j4 include /usr/include/ >/dev/null
real 0m0,856s
user 0m1,028s
sys 0m1,024s
-
- Модератор
- Сообщения: 20348
- Статус: nulla salus bello
- ОС: Debian GNU/Linux
Re: Найти нужные строки во множестве документов
Это у Вас на многогигабайтном каталоге так быстро отработало? Тогда, безусловно, беру свои слова обратно.
Пишите правильно:
в консоли вку́пе (с чем-либо) в общем вообще | в течение (часа) новичок нюанс по умолчанию | приемлемо проблема пробовать трафик |
-
- Сообщения: 2477
- ОС: Gentoo
Re: Найти нужные строки во множестве документов
Ээ , вот это рассказывать не надо, я же лично наблюдал сколько занял поиск в каталоге /usr/include. Как раз grep и отработал где то 19 секунд, в то время как у rg это заняло менее секунды.
Ок сейчас попробую на другом компе выполнить данные команды в другом порядке, сначала rg потом grep, ну и там диск будет немного медленней.
-
- Модератор
- Сообщения: 20348
- Статус: nulla salus bello
- ОС: Debian GNU/Linux
Re: Найти нужные строки во множестве документов
Так только такой случай ТСу и имеет смысл рассматривать. Он, вроде как, не собирается без конца поиск гонять, да и не закешируется его многогигабайтное хозяйство полностью. А сравнения обеих программ с пустым кешем нет.
Добавлено (23:19):
Он занял real. Но за вычетом user и sys останется iowait, который почти всё время и занял.
Пишите правильно:
в консоли вку́пе (с чем-либо) в общем вообще | в течение (часа) новичок нюанс по умолчанию | приемлемо проблема пробовать трафик |
-
- Сообщения: 2477
- ОС: Gentoo
Re: Найти нужные строки во множестве документов
В общем протестировал grep и rg, получились такие результаты:
Протестировал на обычном жестком диске(не ssd), пришлось каждый раз перезагружать комп, чтобы кеш обновлялся, обе утилиты используют один и тот же кеш. Все таки rg будет быстрее grep-а.
А вот при использовании ssd разница в несколько раз:
Spoiler
Shell
# time grep -Rh include /usr/include/ >/dev/null
real 1m42,866s
user 0m0,237s
sys 0m1,232s
# time rg -NI -j4 include /usr/include/ >/dev/null
real 1m26,898s
user 0m0,611s
sys 0m1,664s
# time rg -NI include /usr/include/ >/dev/null
real 1m26,084s
user 0m0,686s
sys 0m1,579s
А вот при использовании ssd разница в несколько раз:
Spoiler
Shell
# time rg -NI -j4 -t txt include /usr/include/ >/dev/null
real 0m1,004s
user 0m0,221s
sys 0m0,234s
# time grep -Rh include /usr/include/ >/dev/null
real 0m18,947s
user 0m0,349s
sys 0m2,282s
-
- Сообщения: 873
- ОС: debian, fedora (i3-wm)
Re: Найти нужные строки во множестве документов
Решила проверить по результату, перед каждым тестом презагружалась:
Только жесткий диск, 4 ядра, 4 потока
Shell
time grep -ohr 'include\|exclude' --include=\*.h /usr/include/ >log.grep
real 0m8,256s
user 0m0,120s
sys 0m0,337s
time grep -ohr 'include\|exclude' --include=\*.h /usr/include/ >log.grep
real 0m8,189s
user 0m0,118s
sys 0m0,332s
time rg -INo -j4 'include|exclude' --glob \*.h /usr/include/ >log.rg
real 0m8,666s
user 0m0,189s
sys 0m0,428s
time rg -INo -j4 'include|exclude' --glob \*.h /usr/include/ >log.rg
real 0m8,061s
user 0m0,179s
sys 0m0,434s
diff <(sort log.rg) <(sort log.grep)
-
- Сообщения: 2477
- ОС: Gentoo
Re: Найти нужные строки во множестве документов
На счет вывода ssd пардон, там команду не ту сделал, там искало в txt файлах, по этому так быстро))
С регулярками позже попробую у себя, пока не до этого.
Spoiler
Shell
# time rg -NI -j4 include /usr/include/ >/dev/null
real 0m16,386s
user 0m1,261s
sys 0m2,529s
-
- Модератор
- Сообщения: 20348
- Статус: nulla salus bello
- ОС: Debian GNU/Linux
Re: Найти нужные строки во множестве документов
Пишите правильно:
в консоли вку́пе (с чем-либо) в общем вообще | в течение (часа) новичок нюанс по умолчанию | приемлемо проблема пробовать трафик |
-
- Сообщения: 4
Re: Найти нужные строки во множестве документов
Вобщем я так понял, что с учетом много гигабайтности даннх grep будет медленым.
Как тогда будет выглядеть команда с какой-то из этих альтернатив grep
https://beyondgrep.com/feature-comparison/
чтобы (напомню) найти во всех вложеных папках во всех этих сотнях гигабайт текстовых документов только строки содержащие нужные имена, например, только строки с "Василий", "Николай", "Максим" и составит из этих строк новый файл .txt
?
Как тогда будет выглядеть команда с какой-то из этих альтернатив grep
https://beyondgrep.com/feature-comparison/
чтобы (напомню) найти во всех вложеных папках во всех этих сотнях гигабайт текстовых документов только строки содержащие нужные имена, например, только строки с "Василий", "Николай", "Максим" и составит из этих строк новый файл .txt
?
-
- Сообщения: 4
Re: Найти нужные строки во множестве документов
Добавлю, что данные хранятся не на ssd а на обычном жестком диске
-
- Сообщения: 873
- ОС: debian, fedora (i3-wm)
Re: Найти нужные строки во множестве документов
Медленной будет состваляющая для открытия и чтения каждого файла которая будет одинакова как для grep так и для rg
Код: Выделить всё
grep -hrw '^\(Василий\|Николай\|Максим\)' --include=\*.txt /path/to/dir/ >log.grep
rg -IN -j4 '^(Василий|Николай|Максим)\b' --glob \*.txt /path/to/dir/ >log.rg
Последний раз редактировалось olecya 08.11.2020 13:49, всего редактировалось 3 раза.
-
- Модератор
- Сообщения: 20348
- Статус: nulla salus bello
- ОС: Debian GNU/Linux
Re: Найти нужные строки во множестве документов
Они все будут медленными. Максимум несколько процентов выиграете, даже в 10% верится с трудом. Если поиск нужно будет гонять часто, а не раз в квартал, займитесь лучше переводом этого хозяйства в нормальную индексируемую БД.
Пишите правильно:
в консоли вку́пе (с чем-либо) в общем вообще | в течение (часа) новичок нюанс по умолчанию | приемлемо проблема пробовать трафик |