Эффективная фильтрация многих файлов по их содержимому с помощью awk / sed / grep

Я хочу перечислить все файлы в каталоге (рекурсивно), у которых вторая строка полностью соответствует определенному регулярному выражению. Общее количество файлов около 60К.

Пока что я составил эту команду: find / path -type f | xargs --no-run-if-empty -n1000 awk 'FNR = 2 && $ 0 ~ / ^ регулярное выражение $ / {print FILENAME; nextfile} '.

Можно ли сделать его более эффективным?

0
05.02.2017, 08:03
2 ответа

Вы можете попробовать:

grep -n <reg expr> /path/to/* | grep ":2:" | cut -d ':' -f1

Пока : 2: не является частью .

Существует также -x для сопоставления всей строки.

Понятия не имею, быстрее ли это - у меня нет 60k файлов для тестирования:]

0
28.01.2020, 02:34

Прежде всего, обратите внимание, что вы по ошибке использовали = вместо правильного == .

Вам не нужны xargs , вы можете запустить его прямо из find . Также как и ваш awk должен завершиться, как только он обработает строку 2, вместо чтения всего файла.

find /path -type f -exec awk 'FNR == 2 && /^regular expression$/ {print FILENAME}; FNR == 2 {nextfile}' '{}' +

+ в конце аргумента -exec инструктирует find поместить как можно больше аргументов имени файла. А-ля xargs . См. Документацию find .

Важным моментом здесь является FNR == 2 {nextfile} .

Вопрос о том, лучше ли -exec , чем xargs (но использовать -print0 & -0 ], если доступно)) является предметом обсуждения. С одной стороны найти… | xargs… допускает некоторое распараллеливание с find , читающим еще несколько имен файлов, в то время как awk проверяет предыдущий пакет. С другой стороны, распараллеливание может привести к плохому удалению диска из-за того, что awk и find будут конкурировать за разные дорожки на диске. Ваше оборудование (размер кеша, SSD и т. Д.) Изменит сделку. Профиль тогда решайте.

2
28.01.2020, 02:34

Теги

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