Eu gostaria de pesquisar recursivamente uma árvore de diretórios e listar o número de arquivos disponíveis em cada pasta que possuem um nome correspondente a uma determinada string. Com efeito, gostaria de retornar resultados de:
ls -l | wc -l
para cada pasta que identifiquei via find
.
Código
O código abaixo lista corretamente o número de arquivos em cada pasta cujo nome contém a string Magic Data .
find /path/to/cool/stuff \
-maxdepth 4 \
-type d \
-name '*Magic Data*' \
-print0 | xargs \
--verbose \
-0 -I {} ls -l {}
Eu gostaria de expandi-lo e canalizar os resultados de ls
para wc -l
.
Tentar
find /path/to/cool/stuff \
-maxdepth 4 \
-type d \
-name '*Magic Data*' \
-print0 | xargs \
--verbose \
-0 -I {} ls -l {} | wc -l
Isso falha e imprime:
ls -l /path/to/cool/stuff/some/folders/Magic Data
ls -l /path/to/cool/stuff/some/folders2/Magic Data
Saída desejada
/path/to/cool/stuff/some/folders/Magic Data 29
/path/to/cool/stuff/some/folders2/Magic Data 30
A saída desejada conteria:
- Caminho completo para a pasta pesquisada
- Saída de
wc -l
, que neste caso reflete a contagem de arquivos não ocultos
Existem duas maneiras principais de resolver isso:
Modifique o
find
comando para que ele entre apenas nos diretórios de seu interesse e imprima um único caractere (por exemplox
, ) para cada arquivo encontrado. Em seguida, conte o número desse caractere produzido comwc -l
. É mais seguro produzir um caractere do que o nome do caminho, pois os nomes do caminho no Unix podem conter novas linhas. Essa solução é um pouco complicada, pois envolve o uso-prune
para ignorar diretórios nos quais não estamos interessados ou, alternativamente,! -path
.Encontre os diretórios exatamente como você fez até agora, mas use um script em linha para fazer a contagem de arquivos dentro. Isso é mais simples, e o que estou mostrando abaixo.
Aqui, encontramos os diretórios como você, então, para cada diretório, executamos este pequeno
bash
script:Isso pega o nome do caminho do diretório da linha de comando (fornecido por
find
) e expande o*
padrão glob dentro dele. Ao definir adotglob
opção shell na linha de comando do script, garantimos que também contaremos arquivos e diretórios ocultos (remova-O dotglob
para não contar nomes ocultos).Fazemos a expansão de todos os nomes como um argumento para
set
, que definirá os parâmetros posicionais para as entradas expandidas. O número de parâmetros posicionais está disponível como$#
, que é, portanto, também a contagem de arquivos nesse diretório específico.Relacionado:
A partir de sua tentativa de solução, é assim que se pode realizar esta tarefa:
Explicação:
find
- ndo os diretórios de destino, sua receita é seguida.{} +
e os entregamos ao shellsh
por meio de sua lista de argumentos:sh -c '...' find_sh {} +
sh
qual é o argumento zero$0
e, como tal, pode receber qualquer nome, e aqui neste caso o nomeamosfind_sh
. Este é o nome que aparecerá na lista de processos.{} +
e forma os$1 $2 $3 ...
argumentos para o shell que estamos gerando.! -name .
OTW, o nome do diretório de destino também é contado na saída wc -l.Você também pode usar o seguinte comando para conseguir o que deseja
Aqui estou usando
exec
para executar osh
shell que está executando o comando dado a ele usando a-c
opção . No seu caso o comando éls -1 | wc -l