UPDATE: Fiz tudo isso abaixo, o que é legal, mas criei uma maneira melhor de classificar diretórios pelo uso de inode:
du --inodes -S | sort -rh | sed -n \
'1,50{/^.\{71\}/s/^\(.\{30\}\).*\(.\{37\}\)$/\1...\2/;p}'
E se você quiser permanecer no mesmo sistema de arquivos, faça:
du --inodes -xS
Aqui está um exemplo de saída:
15K /usr/share/man/man3
4.0K /usr/lib
3.6K /usr/bin
2.4K /usr/share/man/man1
1.9K /usr/share/fonts/75dpi
...
519 /usr/lib/python2.7/site-packages/bzrlib
516 /usr/include/KDE
498 /usr/include/qt/QtCore
487 /usr/lib/modules/3.13.6-2-MANJARO/build/include/config
484 /usr/src/linux-3.12.14-2-MANJARO/include/config
AGORA COM LS:
Várias pessoas mencionaram que não possuem coreutils atualizados e a opção --inodes não está disponível para eles. Então, aqui está o sl:
sudo ls -AiR1U ./ |
sed -rn '/^[./]/{h;n;};G;
s|^ *([0-9][0-9]*)[^0-9][^/]*([~./].*):|\1:\2|p' |
sort -t : -uk1.1,1n |
cut -d: -f2 | sort -V |
uniq -c |sort -rn | head -n10
Isso está me fornecendo resultados praticamente idênticos ao du
comando:
DU:
15K /usr/share/man/man3
4.0K /usr/lib
3.6K /usr/bin
2.4K /usr/share/man/man1
1.9K /usr/share/fonts/75dpi
1.9K /usr/share/fonts/100dpi
1.9K /usr/share/doc/arch-wiki-markdown
1.6K /usr/share/fonts/TTF
1.6K /usr/share/dolphin-emu/sys/GameSettings
1.6K /usr/share/doc/efl/html
LS:
14686 /usr/share/man/man3:
4322 /usr/lib:
3653 /usr/bin:
2457 /usr/share/man/man1:
1897 /usr/share/fonts/100dpi:
1897 /usr/share/fonts/75dpi:
1890 /usr/share/doc/arch-wiki-markdown:
1613 /usr/include:
1575 /usr/share/doc/efl/html:
1556 /usr/share/dolphin-emu/sys/GameSettings:
Eu acho que a include
coisa depende apenas de qual diretório o programa parece primeiro - porque eles são os mesmos arquivos e têm links físicos. Tipo como a coisa acima. Eu posso estar errado sobre isso - e congratulo-me com a correção ...
O método subjacente a isso é que eu substituo cada um dos ls
nomes de arquivos pelo nome de diretório que contém em sed.
Seguindo a partir disso ... Bem, eu também sou um pouco confusa. Tenho certeza de que está contando com precisão os arquivos, como você pode ver aqui:
% _ls_i ~/test
> 100 /home/mikeserv/test/realdir
> 2 /home/mikeserv/test
> 1 /home/mikeserv/test/linkdir
DU DEMO
% du --version
> du (GNU coreutils) 8.22
Faça um diretório de teste:
% mkdir ~/test ; cd ~/test
% du --inodes -S
> 1 .
Alguns diretórios filhos:
% mkdir ./realdir ./linkdir
% du --inodes -S
> 1 ./realdir
> 1 ./linkdir
> 1 .
Faça alguns arquivos:
% printf 'touch ./realdir/file%s\n' `seq 1 100` | . /dev/stdin
% du --inodes -S
> 101 ./realdir
> 1 ./linkdir
> 1 .
Alguns hardlinks:
% printf 'n="%s" ; ln ./realdir/file$n ./linkdir/link$n\n' `seq 1 100` |
. /dev/stdin
% du --inodes -S
> 101 ./realdir
> 1 ./linkdir
> 1 .
Veja os hardlinks:
% cd ./linkdir
% du --inodes -S
> 101
% cd ../realdir
% du --inodes -S
> 101
Eles são contados sozinhos, mas sobe um diretório ...
% cd ..
% du --inodes -S
> 101 ./realdir
> 1 ./linkdir
> 1 .
Em seguida, executei meu script de baixo e:
> 100 /home/mikeserv/test/realdir
> 100 /home/mikeserv/test/linkdir
> 2 /home/mikeserv/test
E Graeme's:
> 101 ./realdir
> 101 ./linkdir
> 3 ./
Então, acho que isso mostra que a única maneira de contar inodes é por inode. E como contar arquivos significa contar inodes, você não pode contar inodes duplamente - contar arquivos com inodes com precisão não pode ser contado mais de uma vez.
VELHO:
Acho isso mais rápido e é portátil:
sh <<-\CMD
{ echo 'here='"$PWD"
printf 'cd "${here}/%s" 2>/dev/null && {
set --
for glob in ".[!.]*" "[!.]*" ; do
set -- $glob "$@" &&
[ -e "./$1" ] || shift
done
printf "%%s\\t%%s\\n" $# "$PWD"
}\n' $( find . -depth -type d 2>/dev/null )
} | . /dev/stdin |
sort -rn |
sed -n \
'1,50{/^.\{71\}/s/^\(.\{30\}\).*\(.\{37\}\)$/\1...\2/;p}'
CMD
Não é necessário -exec
para todos os diretórios - ele usa apenas o sh
processo one ell e one find
. Ainda tenho o set -- $glob
direito de incluir .hidden
arquivos e tudo mais, mas é muito próximo e muito rápido. Você entraria cd
em qualquer diretório raiz para a verificação e pronto.
Aqui está uma amostra da minha saída executada em /usr
:
14684 /usr/share/man/man3
4322 /usr/lib
3650 /usr/bin
2454 /usr/share/man/man1
1897 /usr/share/fonts/75dpi
...
557 /usr/share/gtk-doc/html/gtk3
557 /usr/share/doc/elementary/latex
539 /usr/lib32/wine/fakedlls
534 /usr/lib/python2.7/site-packages/bzrlib
500 /usr/lib/python3.3/test
Também uso sed
na parte inferior para apará-lo para os 50 melhores resultados. head
seria mais rápido, é claro, mas também aparo cada linha, se necessário:
...
159 /home/mikeserv/.config/hom...hhkdoolnlbekcfllmednbl/4.30_0/plugins
154 /home/mikeserv/.config/hom...odhpcledpamjachpmelml/1.3.11_0/js/ace
...
É rude, é verdade, mas foi um pensamento. Outro dispositivo bruto que eu uso é despejar 2>stderr
para ambos find
e cd
para dentro 2>/dev/null
. É mais limpo do que procurar erros de permissão em diretórios que não consigo ler sem acesso root - talvez eu deva especificar isso find
. Bem, é um trabalho em andamento.
Ok, então eu corrigi os globs do shell assim:
for glob in ".[!.]*" "[!.]*" ; do
set -- $glob "$@" &&
[ -e "./$1" ] || shift
done
Na verdade, eu ia fazer uma pergunta sobre como isso poderia ser feito, mas, enquanto digitava o título da pergunta, o site me indicou uma pergunta relacionada sugerida , onde eis que Stephane já pesava . Então isso foi conveniente. Aparentemente, [^.],
embora seja bem suportado, não é portátil e você deve usar o !bang.
que achei no comentário de Stephane lá.
Enfim, apenas puxar arquivos ocultos não era suficiente, obviamente. Então eu tenho que fazer o set
dobro para evitar procurar posicionais pelo literal $glob
. Ainda assim, ele não parece afetar o desempenho e adiciona todos os arquivos no diretório de maneira confiável.