contando o número de diretórios em um diretório específico

103

Como contar o número de pastas em um diretório específico. Estou usando o seguinte comando, mas sempre fornece um extra.

find /directory/ -maxdepth 1 -type d -print| wc -l

Por exemplo, se eu tiver 3 pastas, este comando fornece 4. Se ele contém 5 pastas, o comando fornece 6. Por que isso?

user2566898
fonte
4
A contagem adicional de 1 está lá devido ao diretório atual '.' , que também é levado em consideração por 'find'.
patel deven

Respostas:

94

find também está imprimindo o próprio diretório:

$ find .vim/ -maxdepth 1 -type d
.vim/
.vim/indent
.vim/colors
.vim/doc
.vim/after
.vim/autoload
.vim/compiler
.vim/plugin
.vim/syntax
.vim/ftplugin
.vim/bundle
.vim/ftdetect

Em vez disso, você pode testar os filhos do diretório e não descer até eles:

$ find .vim/* -maxdepth 0 -type d
.vim/after
.vim/autoload
.vim/bundle
.vim/colors
.vim/compiler
.vim/doc
.vim/ftdetect
.vim/ftplugin
.vim/indent
.vim/plugin
.vim/syntax

$ find .vim/* -maxdepth 0 -type d | wc -l
11
$ find .vim/ -maxdepth 1 -type d | wc -l
12

Você também pode usar ls:

$ ls -l .vim | grep -c ^d
11


$ ls -l .vim
total 52
drwxrwxr-x  3 anossovp anossovp 4096 Aug 29  2012 after
drwxrwxr-x  2 anossovp anossovp 4096 Aug 29  2012 autoload
drwxrwxr-x 13 anossovp anossovp 4096 Aug 29  2012 bundle
drwxrwxr-x  2 anossovp anossovp 4096 Aug 29  2012 colors
drwxrwxr-x  2 anossovp anossovp 4096 Aug 29  2012 compiler
drwxrwxr-x  2 anossovp anossovp 4096 Aug 29  2012 doc
-rw-rw-r--  1 anossovp anossovp   48 Aug 29  2012 filetype.vim
drwxrwxr-x  2 anossovp anossovp 4096 Aug 29  2012 ftdetect
drwxrwxr-x  2 anossovp anossovp 4096 Aug 29  2012 ftplugin
drwxrwxr-x  2 anossovp anossovp 4096 Aug 29  2012 indent
drwxrwxr-x  2 anossovp anossovp 4096 Aug 29  2012 plugin
-rw-rw-r--  1 anossovp anossovp 2505 Aug 29  2012 README.rst
drwxrwxr-x  2 anossovp anossovp 4096 Aug 29  2012 syntax

$ ls -l .vim | grep ^d
drwxrwxr-x  3 anossovp anossovp 4096 Aug 29  2012 after
drwxrwxr-x  2 anossovp anossovp 4096 Aug 29  2012 autoload
drwxrwxr-x 13 anossovp anossovp 4096 Aug 29  2012 bundle
drwxrwxr-x  2 anossovp anossovp 4096 Aug 29  2012 colors
drwxrwxr-x  2 anossovp anossovp 4096 Aug 29  2012 compiler
drwxrwxr-x  2 anossovp anossovp 4096 Aug 29  2012 doc
drwxrwxr-x  2 anossovp anossovp 4096 Aug 29  2012 ftdetect
drwxrwxr-x  2 anossovp anossovp 4096 Aug 29  2012 ftplugin
drwxrwxr-x  2 anossovp anossovp 4096 Aug 29  2012 indent
drwxrwxr-x  2 anossovp anossovp 4096 Aug 29  2012 plugin
drwxrwxr-x  2 anossovp anossovp 4096 Aug 29  2012 syntax
Pavel Anossov
fonte
Agradável! Como você faria isso $ ls -l .vimcom o PHP? Ou como obter apenas o total, sem a lista. Quer dizer, neste caso, obter apenas 52?
Pathros
Hah. Adoro como o argumento contra o PowerShell é que o BASH é mais fácil em todos os sentidos ... deseja ver o comando POSH para fazer isso? (ls).Count
Kolob Canyon
@Pathros Use glob com o sinalizador GLOB_ONLYDIR e conte () o resultado.
Pilipe
1
ls -l | grep -c ^dé muito simples e funciona. @Pathros provavelmente é uma maneira melhor em PHP, mas no pior caso em PHP você sempre pode usar a função shell_exec () para executar a linha de comando e retornar os resultados para uma string. ou seja $dirCount = shell_exec('ls -l | grep -c ^d');
gigabyte de
66

Obtenha uma contagem apenas dos diretórios no diretório atual

echo */ | wc

você vai sair e colocar como 1 309 4594

2nd digitrepresenta não. de diretórios.

ou

tree -L 1 | tail -1

EmptyData
fonte
8
Isso falhará se houver espaços nos nomes dos diretórios, infelizmente.
Michael Campbell
zsh: no matches found: */precisa de nullglob
Anne van Rossum
@AnnevanRossum Você tem echo. tipowhich echo
EmptyData
7
O primeiro pode ser melhorado um pouco:echo */ | wc -w
ibic
Observe que isso contará 1 se não houver diretórios em vez de 0.
jinawee
27
find . -mindepth 1 -maxdepth 1 -type d | wc -l

Pois encontrar -mindepthsignifica número total não permitido nos diretórios

-maxdepth significa número total de recusas em diretórios

-type d significa diretório

E para wc -lmeios conta as linhas da entrada

Shiyani Suresh
fonte
2
Você pode explicar sua resposta, por favor (dentro de sua resposta)?
Zulu
-mindepth significa número total não permitido nos diretórios, -maxdepth significa número total não permitido nos diretórios, -tipo d significa diretório e wc -l significa contagem de linhas de uma determinada lista de diretórios
shiyani suresh
find . -mindepth 1 -maxdepth 1 -type d | wc -lfornecerá muitos espaços entre o número, por exemplo: `2` você pode evitar usando este: dir_count=`find . -maxdepth 1 -type d | wc -l | xargs`; echo $dir_count # will print just 2 e pode ser útil para condições, como:if (( $dir_count > 1 )); then echo "Yaa"; fi # will print "Yaa"
naorz
16

Se você tiver apenas diretórios na pasta e nenhum arquivo, será o seguinte:

ls | wc -l
Brainmaniac
fonte
2
Também obtém arquivos, mas a questão era sobre pastas / diretórios.
Robert
12

A melhor maneira de navegar até sua unidade e simplesmente executar

ls -lR | grep ^d | wc -l

e localizar todas as pastas no total, incluindo subdiretórios?

find /mount/point -type d | wc -l

... ou encontrar todas as pastas no diretório raiz (sem incluir subdiretórios)?

find /mount/point -maxdepth 1 -type d | wc -l

Felicidades!

Manish Shrivastava
fonte
Observe que o ls anterior -lRignora o diretório com prefixo de ponto enquanto os find -type d conta. Portanto, a contagem fornecida pelo primeiro comando está errada se você tiver diretórios com prefixo de ponto (por exemplo, você tem subdiretório .git!). Você não pode simplesmente usar -lRaporque também obtém para cada diretório uma entrada .e ... Aplica-se também à resposta de @Pavel Anossov
marcz
12

Execute stat -c %h foldere subtraia 2 do resultado. Isso emprega apenas um único subprocesso, em oposição aos 2 (ou mesmo 3) exigidos pela maioria das outras soluções aqui (normalmente findmais wc).

Usando sh / bash:

cnt = $ ((`stat -c% h folder` - 2))
echo $ cnt # 'echo' é um sh / bash embutido, não um processo adicional

Usando csh / tcsh:

@ cnt = `stat -c% h folder` - 2
echo $ cnt # 'echo' é um csh / tcsh embutido, não um processo adicional


Explicação: stat -c %h folderimprime o número de links físicos para a pasta e cada subpasta dentro da pasta contém uma entrada ../ que é um link físico de volta para a pasta . Você deve subtrair 2 porque há dois hardlinks adicionais na contagem:

  1. entrada auto-referencial da própria pasta ./, e
  2. pasta ligação do pai 's para pasta
textral
fonte
Relacionado a esta questão: [Por que um novo diretório tem uma contagem de links físicos de 2 antes de qualquer coisa ser adicionada a ele? ] ( unix.stackexchange.com/questions/101515 ) Isso explica por que essa é uma resposta excelente. Infelizmente, isso não recebeu atenção suficiente! Embora seja uma boa resposta, o resultado depende infelizmente do sistema de arquivos, mas para a maioria dos sistemas de arquivos comuns, isso funcionará.
kvantour de
8

Eu acho que o mais fácil é

  ls -ld images/* | wc -l

onde imagesestá o seu diretório de destino. O sinalizador -d limita os diretórios, e o sinalizador -l executará uma listagem por linha, compatível com o muito familiar wc -lpara contagem de linha.

Briceburg
fonte
Também retorna o resultado +1
Josef,
1
De acordo com man ls, -ddoes: "lista os próprios diretórios, não seus conteúdos", ou seja, se você executar ls /tmp, obterá o que está dentro /tmp, e se executar, ls -d /tmpapenas obterá /tmp. A -dopção não filtra diretórios, conforme solicitado.
Robert
5

Alguns exemplos úteis:

contar arquivos no diretório atual

/bin/ls -lA  | egrep -c '^-'

contar dirs no diretório atual

/bin/ls -lA  | egrep -c '^d'

contar arquivos e diretórios no diretório atual

/bin/ls -lA  | egrep -c '^-|^d'

conte os arquivos e diretórios em um subdiretório

/bin/ls -lA  subdir_name/ | egrep -c '^-|^d'

Notei uma coisa estranha (pelo menos no meu caso):

Quando eu tentei com lsem vez /bin/ls do -Aparâmetro do not list implied . and ..não funcionar tão espected. Quando eu uso lsaquele show ./ e ../ Então esse resultado conta incorretamente. SOLUÇÃO: em /bin/lsvezls

MTK
fonte
4

Número do diretório que podemos encontrar usando o comando abaixo

ls -l | grep "^d" | wc -l

user1388547
fonte
ls -l | grep ^d | wc -l"
servirei
3

Uma solução bash pura:

shopt -s nullglob
dirs=( /path/to/directory/*/ )
echo "There are ${#dirs[@]} (non-hidden) directories"

Se você também quiser contar os diretórios ocultos:

shopt -s nullglob dotglob
dirs=( /path/to/directory/*/ )
echo "There are ${#dirs[@]} directories (including hidden ones)"

Observe que isso também contará links para diretórios. Se você não quiser isso, é um pouco mais difícil com esse método.


Usando find:

find /path/to/directory -type d \! -name . -prune -exec printf x \; | wc -c

O truque é gerar um xpara stdout cada vez que um diretório for encontrado e, em seguida, usar wcpara contar o número de caracteres. Isso contará o número de todos os diretórios (incluindo os ocultos), excluindo os links.


Os métodos apresentados aqui estão todos protegidos contra caracteres engraçados que podem aparecer em nomes de arquivo (espaços, novas linhas, caracteres glob, etc.).

gniourf_gniourf
fonte
Esta é a melhor solução apresentada nesta questão e sempre funcionará!
kvantour de
3

Usando zsh:

a=(*(/N)); echo ${#a}

O Né um nullglob, /faz com que corresponda a diretórios, #contagens. Ele lidará perfeitamente com os espaços nos nomes dos diretórios e também retornará 0se não houver diretórios.

Anne van Rossum
fonte
0

Contar todos os arquivos e subpastas, estilo do Windows:

dir=/YOUR/PATH;f=$(find $dir -type f | wc -l); d=$(find $dir -mindepth 1 -type d | wc -l); echo "$f Files, $d Folders"
margenn
fonte
0

Se você quiser usar expressões regulares, tente:

ls -c | grep "^d" | wc -l
Makassi
fonte
1
Você gostaria de adicionar alguma explicação à sua resposta apenas de código? Isso ajudaria a combater o equívoco de que StackOverflow é um serviço gratuito de escrita de código. Além disso, dê uma olhada aqui para melhorar a aparência: stackoverflow.com/editing-help
Yunnosch
0

A melhor resposta para o que você quer é

echo `find . -maxdepth 1 -type d | wc -l`-1 | bc

isso subtrai um para remover o indesejado '.' diretório que encontra listas (como patel deven mencionado acima).

Se você quiser contar as subpastas recursivamente, basta deixar a opção maxdepth, então

echo `find . -type d | wc -l`-1 | bc

PS Se você achar a substituição de comandos feia, subtrair um pode ser feito como um fluxo puro usando sede bc.

Subtraindo um da contagem:

find . -maxdepth 1 -type d | wc -l | sed 's/$/-1\n/' | bc

ou, adicionando a contagem a menos um:

find . -maxdepth 1 -type d | wc -l | sed 's/^/-1+/' | bc
Dr. Pessoa Pessoa II
fonte
-1

Melhor maneira de fazer isso:

ls -la | grep -v total | wc -l

Isso dá a você a contagem perfeita.

Manoj
fonte
6
Quer dizer que é a pior maneira de fazer isso! além disso, isso não conta o número de diretórios. E se houver um nome de diretório que contenha a string total? seu método está quebrado :(. Não analisels !
gniourf_gniourf