Quero encontrar um subdiretório do diretório atual, que (que é o subdiretório) contém 2 ou mais arquivos regulares.
Não estou interessado em diretórios contendo menos de 2 arquivos, nem em diretórios que contêm apenas subdiretórios.
Aqui está uma abordagem completamente diferente baseada no GNU find
e uniq
. Isso é muito mais rápido e mais amigável à CPU do que as respostas baseadas na execução de um comando shell que conta os arquivos para cada diretório encontrado.
find . -type f -printf '%h\n' | sort | uniq -d
O find
comando imprime o diretório de todos os arquivos na hierarquia e uniq
exibe apenas os diretórios que aparecem pelo menos duas vezes.
find
. Nesse caso, porque o GNUfind
irá alterar os nomes dos diretórios que possuem caracteres que não podem ser impressos no local atual (como "ä" no local C). Veja também unix.stackexchange.com/questions/321697/…-printf '%h\0' | sort -z | uniq -zd | xargs -r0 ...
Isso localizará todos os nomes no diretório atual ou abaixo dele e, em seguida, filtrará todos os nomes que não sejam nomes de diretórios.
Os nomes de diretório restantes serão atribuídos a este script curto:
Esse script contará o número de arquivos regulares (pulando links simbólicos) no diretório fornecido como o primeiro argumento da linha de comando (de
find
). O último comando no script é um teste para verificar se a contagem foi 2 ou superior. O resultado desse teste é o valor de retorno (status de saída) do script.Se o teste bem sucedido,
-print
irá causarfind
para imprimir o caminho para o diretório.Para também considerar arquivos ocultos (arquivos cujos nomes começam com um ponto), altere o
sh -c
script dizendopara
Teste:
fonte
[ "" -ge 2 ]
é um teste válido.dash
,bash --posix
Etest
toda a exibição uma mensagem de erro e de saída com duas (ou seja, "Erro")ksh
está sendo executado comosh
. Irá alterar imediatamente. Obrigado por me cutucar! :-)[ -f ... ]
desreferencia links simbólicos. Você deve adicionar um teste para eliminá-los, pois a pergunta especifica que apenas os arquivos regulares devem ser contados.Com a ajuda da resposta de Gilles no SU e seu reverso e algumas modificações, aqui está o que você precisa.
Árvore de diretórios.
Resultado:
fonte
test
osdir2
diretórios e os arquivos na minha configuração de teste (veja minha resposta).test/x1
e tambémtest/x2
como arquivos ...$1
e$2
serão diretórios paratest
, e o diretório será perdido.Outra
find
+wc
abordagem:path/currdir
- caminho para o seu diretório atual-maxdepth 1
- considere apenas subpastas filho diretas! -empty
- ignorar subpastas vazias! -path "path/currdir"
- ignora o caminho do diretório atualcount=$(find "$1" -maxdepth 1 -type f | wc -l)
-count
é atribuído com o número de arquivos para cada subpasta encontrada[ $count -ge 2 ] ... -print
- imprime o nome / caminho da subpasta contendo 2 ou mais arquivos regularesfonte