Почему поиск + sed поиск и замена медленнее, чем grep -r

62
7

Я пытаюсь выполнить поиск и заменить в репозитории (около 200 мБ, 3000 файлов), и я обнаружил, что он очень медленный по сравнению с grep для одного и того же выражения. Даже жесткое количество матчей довольно низкое (пара 100), поэтому запасная часть не должна сильно замедлять ее.

Используемые команды:

time grep -r 'home' .

real 0m0.228s
user 0m0.154s
sys 0m0.071s

time find . -type f -exec sed -i 's/home/test/g' {} \;

real 0m38.064s
user 0m8.893s
sys 0m28.552s

time find . -type f -exec sed -i 's/home/test/g' {} +

real 0m25.671s
user 0m5.654s
sys 0m19.968s

time find . -type f

real 0m0.090s
user 0m0.013s
sys 0m0.028s

Что здесь происходит? И есть ли способ ускорить его с помощью другой команды?

спросил(а) 2021-01-19T18:03:53+03:00 2 месяца, 3 недели назад
1
Решение
62

Медленная часть, вероятно, sed переписывает каждый файл - она должна делать это для каждого файла, даже тех, которые не совпадают. Если большинство файлов не совпадают, вы можете ускорить его, используя grep для создания списка подходящих файлов (вы знаете, что это быстро), а затем подача этого sed чтобы переписать их.

grep -r -l 'home' . | while read -r filename; do
sed -i 's/home/test/g' "$filename"
done

Параметр -l для grep сообщает, что он печатает только имена файлов, которые соответствуют.

Если вы используете GNU grep вы можете сделать это еще более безопасным и эффективным, используя -Z для нулевого завершения имен файлов; то имена файлов, содержащие новую строку, не будут проблемой.

grep -rlZ 'home' . | xargs -0 sed -i 's/home/test/g/ {} +

ответил(а) 2021-01-19T18:03:53+03:00 2 месяца, 3 недели назад
Ваш ответ
Введите минимум 50 символов
Чтобы , пожалуйста,
Выберите тему жалобы:

Другая проблема