Encontre ocorrências em uma lista de arquivos e conte-as

Encontre ocorrências em uma lista de arquivos e conte-as

Eu tenho um grande conjunto de despejos de threads que estão em uma árvore de diretórios (uma pasta para cada 30 minutos).

Estou tentando contar quantos Threads existem em um único arquivo. Até agora eu descobri:

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

Isso retorna:

./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]
. . . . . .

É um bom começo, porém preciso encadeá-lo com um 'wc -l' para saber para cada arquivo quantos Threads existem. Estou fazendo algumas tentativas, mas todas estão falhando:

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

Você tem uma ideia se isso é possível com find ou preciso escrever um script que verifique dir por dir cada arquivo?

Responder1

Você não pode canalizar wc -lpara o grepcomando -execsem usar uma invocação explícita do shell com sh -cie

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

Mas executar isso faznãoproduza os nomes dos arquivos nos quais os padrões são encontrados. Para fazer isso de forma confiável, sugira usar um loop de shell interno sh -cque imprima o nome do arquivo e a contagem de palavras associadas

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

Ou use grepsozinho sem localizar, fazendo uso do --includesinalizador (variantes GNU/BSD) que permite fornecer uma expressão glob para pesquisar apenas esses arquivos durante a recorrência

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

Eu sugeriria também usarripgrepque busca arquivos recursivamente por padrão e é muito mais rápido (fonte). Em que você poderia simplesmente fazer

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

informação relacionada