Найти вхождения в списке файлов и подсчитать их

Найти вхождения в списке файлов и подсчитать их

У меня есть большой набор дампов потоков, которые находятся в дереве каталогов (одна папка на каждые 30 минут).

Я пытаюсь посчитать, сколько потоков в одном файле. Пока что у меня получилось:

find . -name 'high-cpu-tdump.out' -exec grep -H "Thread-" {} \;

Это возвращает:

./cbsmtjfuprd2/2021.10.22-06.30/high-cpu-tdump.out:"Thread-0 (HornetQ-server-HornetQServerImpl::serverUUID=7582b137-83b1-11e9-bc0d-b5863efb47a2-961209098)" #123 prio=5 os_prio=0 tid=0x00007f01a45be000 nid=0x4a4 waiting on condition [0x00007f010b730000]
./cbsmtjfuprd2/2021.10.22-06.30/high-cpu-tdump.out:"Thread-1 (HornetQ-scheduled-threads-2107959528)" #121 prio=5 os_prio=0 tid=0x00007f01c01ff800 nid=0x4a2 waiting on condition [0x00007f0130897000]
./cbsmtjfuprd2/2021.10.22-06.30/high-cpu-tdump.out:"Thread-0 (HornetQ-Asynchronous-Persistent-Writes221963927-1847608919)" #120 daemon prio=5 os_prio=0 tid=0x00007f01a4527000 nid=0x49a waiting on condition [0x00007f0131487000]
./cbsmtjfuprd2/2021.10.22-06.30/high-cpu-tdump.out:"Thread-0 (HornetQ-scheduled-threads-2107959528)" #116 prio=5 os_prio=0 tid=0x00007f01a4377800 nid=0x490 waiting on condition [0x00007f0131ce4000]
. . . . . .

Это хорошее начало, однако мне нужно связать это с 'wc -l', чтобы знать, сколько потоков находится в каждом файле. Я делаю несколько попыток, но все они терпят неудачу:

find . -name 'high-cpu-tdump.out' -exec grep -H "Thread-" {} | wc -l \;
find: missing argument to `-exec'

Есть ли у вас идеи, можно ли это сделать с помощью find или мне придется написать скрипт, который будет проверять каталог за каталогом для каждого отдельного файла?

решение1

Вы не можете передать wc -lкоманду grepкак часть -execбез явного вызова оболочки с помощью sh -cie

find  . -name 'high-cpu-tdump.out' -exec sh -c 'grep -H "Thread-" {} | wc -l' ';'

Но запуск этого делаетнетвывести имена файлов, в которых найдены шаблоны. Чтобы сделать это надежно, предложите использовать цикл оболочки внутри, sh -cкоторый печатает имя файла и связанное с ним количество слов

find . -name 'high-cpu-tdump.out' -exec sh -c '
    for file; do printf "%s %s\n" "file" $(grep -c "Thread-" "$file") ; done' -- {} +

Или используйте его grepотдельно, без find, используя --includeфлаг (варианты GNU/BSD), который позволяет задать выражение glob для поиска только этих файлов при рекурсии.

grep -r -c 'Thread-' --include='high-cpu-tdump.out' .

Я бы также предложил использоватьрипгрепкоторый по умолчанию рекурсивно ищет файл и работает намного быстрее (источник). В котором вы могли бы просто сделать

rg -c 'Thread-' -g 'high-cpu-tdump.out'

Связанный контент