Как ускорить этот поиск в fgrep / Ag?

Возможно, это может помочь, если у вас есть более одного случая в строке, а не вложенность:

#cat plop
>a & b & c <ex> a & b & c </ex> a & b & c <ex> a & b & c </ex> a & b & c

#cat plop |sed -e :1 -e 's@\(<ex>[^(</ex>)]*\)&\(.*</ex>\)@\1+\2@;t1'     
>a & b & c <ex> a + b + c </ex> a & b & c <ex> a + b + c </ex> a & b & c
6
25.12.2016, 12:05
2 ответа

Возможно, вы могли бы сделать это немного быстрее, выполнив несколько вызовов find параллельно.Например, сначала получите все каталоги верхнего уровня и выполните N вызовов поиска, по одному для каждого каталога. Если вы запустите в подоболочке, вы можете собрать вывод и передать его vim или чему-нибудь еще:

shopt -s dotglob ## So the glob also finds hidden dirs
( for dir in $HOME/*/; do 
    find -L "$dir" -xtype f -name "*.tex" -exec grep -Fli and {} + & 
  done
) | vim -R -

Или, чтобы убедиться, что вы начнете получать вывод только после того, как все находки будут завершены:

( for dir in $HOME/*/; do 
    find -L "$dir" -xtype f -name "*.tex" -exec grep -Fli and {} + & 
  done; wait
) | vim -R -

Я провел несколько тестов и скорость для вышеупомянутого действительно была немного выше, чем у единственной находки . В среднем, более 10 запусков, одно средство вызова find - 0,898 секунды, а приведенная выше подоболочка - запуск одного поиска для каждого каталога - 0,628 секунды.

Я предполагаю, что детали всегда будут зависеть от того, сколько каталогов у вас есть в $ HOME , сколько из них может содержать файлы .tex и сколько может совпадать, так что ваш пробег может различаться.

4
27.01.2020, 20:24

Поскольку вы используете ack и Silver Searcher ( ag ), кажется, что вы можете использовать дополнительные инструменты.

Новый инструмент в этой области - ripgrep ( rg ). Он разработан, чтобы быть быстрым как при поиске файлов для поиска (например, ag ), так и при поиске самих файлов (как старый добрый GNU grep ).

В качестве примера в вашем вопросе вы можете использовать его примерно так:

rg --files-with-matches --glob "*.tex" "and" "$HOME"

Автор ripgrep опубликовал подробный анализ того, как работают различные инструменты поиска, а также сравнительные тесты.

Один из тестов, linux-literal-casei , в некоторой степени похож на задачу, которую вы описываете. Он выполняет поиск по большому количеству файлов во множестве вложенных каталогов (кодовая база Linux), ища строковый литерал без учета регистра.

В этом тесте rg был самым быстрым при использовании белого списка (например, в вашем примере с «* .tex»). Инструмент ucg также хорошо показал себя в этом тесте.

 rg (игнорировать) 0,345 +/- 0,073 (строки: 370) 
rg (игнорировать) (mmap) 1,612 +/- 0,011 (строки: 370) 
ag (игнорировать) (mmap ) 1,609 +/- 0,015 (строки: 370) 
pt (игнорировать) 17,204 +/- 0,126 (строки: 370) 
просеять (игнорировать) 0,805 +/- 0,005 (строки: 370) { {1}} git grep (игнорировать) 0,343 +/- 0,007 (строки: 370) 
rg (белый список) 0,222 +/- 0,021 (строки: 370) + 
ucg (белый список) 0,217 + / - 0,006 (строк: 370) * 
 

* - Лучшее среднее время. + - Лучшее время выборки.

Автор исключил ack из тестов, потому что он был намного медленнее других.

6
27.01.2020, 20:24

Теги

Похожие вопросы