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 -l
para o grep
comando -exec
sem usar uma invocação explícita do shell com sh -c
ie
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 -c
que 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 grep
sozinho sem localizar, fazendo uso do --include
sinalizador (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'