Самый быстрый способ перечислить все имена файлов, содержимое которых может соответствовать любой из нескольких строк - PullRequest
0 голосов
/ 01 февраля 2019

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


$ cat ../Identifiers.list | xargs -i grep -l "{}" .

Это заняло около 8 минут, чтобы напечатать все имена файлов.Есть ли более быстрый способ?


Identifiers.list - содержимое файла ниже

287434
383460
633491
717255
827734
253735
635373
553888
910366

Нет файлов в каталоге - 36000

$ ls -l *.xml | wc -l
36000

Ответы [ 2 ]

0 голосов
/ 02 февраля 2019

поместите строки в одно регулярное выражение:

(?:287434|383460|633491|717255|827734|253735|635373|553888|910366)

и затем grep:

grep -P '(?:287434|383460|633491|717255|827734|253735|635373|553888|910366)' *

0 голосов
/ 01 февраля 2019

Я бы сделал это наоборот:

printf '%s\0' *.xml | xargs -0 grep -lFf ../Identifiers.list

Это проверит каждый файл только один раз и остановится, как только совпадение будет найдено.-F использует фиксированное сопоставление строк вместо регулярных выражений, что должно еще больше ускорить процесс.

Я думаю, что ваш подход неявно использует -L 1 (из-за -i), поэтому для каждой строки Identifier.list, он просматривает все файлы.

Потенциально еще быстрее с распараллеливанием, например, с четырьмя параллельными процессами:

printf '%s\0' *.xml | xargs -0 -P 4 grep -lFf ../Identifiers.list

Для еще большего ускорения, если ваши файлы ASCII, вы можете использовать LC_ALL=C:

printf '%s\0' *.xml | LC_ALL=C xargs -0 -P 4 grep -lFf ../Identifiers.list

Использование xargs - хорошая идея, хотя даже без распараллеливания: прямое использование grep, как в

grep -lFf ../Identifiers.list *.xml

, может привести к ошибке, поскольку*.xml расширяется до слишком длинной командной строки.

...