LINUX.ORG.RU

bash+grep оптимизация скрипта


0

0

Есть скажем 100 текстовых файлов, весом 800 мегабайт в сумме. Нужно выбрать строки в которых содержится определенное слово в отдельный файл.

Банальный однопоточный grep blabla filelist и более модный awk .. filelist тратит очень много времени на обработку.

Кто-нибудь писал что-нить подобное, только более скоростное? Я уже подумываю скармливать раз в сутки все файлы в mysql с индексацией, но все же надеюсь что можно добиться больших успехов с шелом.

★★★★★

Хм. Мне одному кажется, что grep/awk работают на скорости, не такой уж далёкой от предела? Один фиг самые ресурсоёмкие операции - чтение строки из файла, поиск по регулярке особо не ускоришь никакой БД?

JackYF ★★★★
()
Ответ на: комментарий от JackYF

я вот только что нашел

Написал греп на перле

for i in *;do perl -ne 'print if /.*xxx.*/;' < $i;done > ../log

все логи обработались секунд за 30. Я в шоке. Когда греп парился минут 10 и я его прибивал недождавшись конца.

mrdeath ★★★★★
() автор топика
Ответ на: комментарий от mrdeath

ничего не понимаю.

# time for i in *;do grep xxxx $i;done > ../log

real	0m33.378s

# ls --si -l ../log
-rw-r--r-- 1 root root 604M Apr 21 20:43 ../log

пошел прямить руки.

mrdeath ★★★★★
() автор топика
Ответ на: комментарий от mrdeath

дятел. Проблема в следующей строчке. sed этот самый 600меговый файл долго обрабатывает. Ладно, попробую на perl'е сейчас

mrdeath ★★★★★
() автор топика

> grep blabla filelist

Ну и балбес. Поиск regexp'ов в несколько раз медленнее. use fgrep, Luke.

fgrep blabla filelist
или
grep -F blabla filelist

Более реальный пример:
fgrep -ri fuck /usr/src/
или
fgrep -rif - /usr/src
fuck
shit
fluff
quirk
fixme
xxx
^D

-F, --fixed-strings
	Interpret  PATTERN as a list of fixed strings, separated by new-
	lines, any of which is to be matched.

anonymous
()
Ответ на: комментарий от anonymous

(~). time grep >/dev/null -ri lol /usr/src/
223.146u 20.594s 6:08.35 66.1%  119+3001k 0+0io 0pf+0w
(~). time fgrep >/dev/null -ri lol /usr/src/
2.352u 19.561s 1:27.31 25.0%    121+3072k 0+0io 0pf+0w

Подумаешь, лишние 5 минут — пустяк.

anonymous
()
Ответ на: комментарий от anonymous

Скобки для группирования тоже дают тормоза:
(~). time grep >/dev/null -ri '\(lol\)' /usr/src/
247.217u 20.622s 6:50.38 65.2%  118+3001k 0+0io 1pf+0w

Здесь еще не очень большие, но на примерах с sed у меня иногда выходило, что более чем в два раза.

Еще быстрее можно погрепать, если задействовать mmap(2). К сожалению не могу протестировать, ибо у меня на тачке памяти мало и могу уйти полностью в swap. :\

--mmap
	If  possible, use the mmap(2) system call to read input, instead
	of the default read(2) system call.  In some situations,  --mmap
	yields  better performance.  However, --mmap can cause undefined
	behavior (including core dumps) if an input file  shrinks  while
	grep is operating, or if an I/O error occurs.

anonymous
()
Ответ на: комментарий от JackYF

Если данные меняются гораздо реже, чем по ним производится поиск, то выгоднее их проиндексировать и искать по индексу. Об обработке регулярных выражений автор не говорил. Хотя даже на индексах можно сделать поддержку несложных шаблонов и все равно будет гораздо быстрее, чем каждый раз читать все данные.

Только не MySQL, а просто отдельный движок инвертированных индексов взять. Наверняка такие есть. Или написать самому / выдрать из свободного поисковика.

anonymous
()
Ответ на: комментарий от mrdeath

> Когда греп парился минут 10 и я его прибивал недождавшись конца.

у некоторых версий гну грепа есть 1000-кратное падение скорости при использовании нетривиальных локалей. Советую сделать перед грепом export LC_ALL=C

dilmah ★★★★★
()
Ответ на: комментарий от stassats

Угу, Перловые регэкспы -- не-Ъ. Есть такая хрень.

balodja ★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.