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?


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

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


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


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

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!


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

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.


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


4

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

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


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.).


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.


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"

0

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

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

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

-1

Melhor maneira de fazer isso:

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

Isso dá a você a contagem perfeita.


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
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.