find
최대 파일 수를 포함하는 디렉토리 목록을 생성하는 방법 . 목록이 가장 높은 것부터 낮은 것 순으로 정렬되기를 원합니다. 나는 목록의 깊이가 1레벨이 되기를 원하며 일반적으로 파일 시스템의 최상위에서 이 명령을 실행합니다 /
.
답변1
업데이트: 나는 아래의 모든 작업을 수행했습니다. 이는 훌륭하지만 다음을 사용하여 inode별로 디렉토리를 정렬하는 더 좋은 방법을 알아냈습니다.
du --inodes -S | sort -rh | sed -n \
'1,50{/^.\{71\}/s/^\(.\{30\}\).*\(.\{37\}\)$/\1...\2/;p}'
동일한 파일 시스템을 유지하려면 다음을 수행하십시오.
du --inodes -xS
다음은 출력의 몇 가지 예입니다.
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
이제 LS와 함께:
몇몇 사람들은 최신 coreutils가 없고 --inodes 옵션을 사용할 수 없다고 언급했습니다. 따라서 이것은 ls입니다.
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
이는 다음 명령과 거의 동일한 결과를 제공합니다 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:
나는 include
프로그램이 처음에 어느 디렉토리를 보는지에 따라 다르다고 생각합니다. 왜냐하면 그것들은 동일한 파일이고 하드 링크되어 있기 때문입니다. 위와 같은 내용입니다. 제가 틀렸을 수도 있지만, 정정을 환영합니다...
작동하는 기본 방식은 ls
각 파일 이름을 해당 파일이 포함된 디렉터리 이름으로 바꾸는 것입니다. 그러면 sed.
그 이후로는... 음, 제 자신도 약간 헷갈리게 됩니다. 여기에서 볼 수 있듯이 파일 수를 정확하게 계산하고 있다고 확신합니다.
% _ls_i ~/test
> 100 /home/mikeserv/test/realdir
> 2 /home/mikeserv/test
> 1 /home/mikeserv/test/linkdir
Dudemore
% du --version
> du (GNU coreutils) 8.22
테스트 디렉터리를 만듭니다.
% mkdir ~/test ; cd ~/test
% du --inodes -S
> 1 .
일부 어린이 카탈로그:
% mkdir ./realdir ./linkdir
% du --inodes -S
> 1 ./realdir
> 1 ./linkdir
> 1 .
파일을 만드세요:
% printf 'touch ./realdir/file%s\n' `seq 1 100` | . /dev/stdin
% du --inodes -S
> 101 ./realdir
> 1 ./linkdir
> 1 .
일부 하드 링크:
% printf 'n="%s" ; ln ./realdir/file$n ./linkdir/link$n\n' `seq 1 100` |
. /dev/stdin
% du --inodes -S
> 101 ./realdir
> 1 ./linkdir
> 1 .
하드 링크 보기:
% cd ./linkdir
% du --inodes -S
> 101
% cd ../realdir
% du --inodes -S
> 101
개별적으로 계산되지만 디렉터리에서 한 수준 위입니다.
% cd ..
% du --inodes -S
> 101 ./realdir
> 1 ./linkdir
> 1 .
그런 다음 아래에서 실행 스크립트를 실행합니다.
> 100 /home/mikeserv/test/realdir
> 100 /home/mikeserv/test/linkdir
> 2 /home/mikeserv/test
그리고 Graeme의 말은:
> 101 ./realdir
> 101 ./linkdir
> 3 ./
따라서 이는 인덱스 노드를 계산하는 유일한 방법은 인덱스 노드를 사용하는 것임을 나타냅니다. 그리고 파일 수를 세는 것은 inode 수를 계산하는 것을 의미하므로 inode를 두 번 계산할 수 없습니다. 파일을 정확하게 계산하기 위해 inode를 두 번 이상 계산할 수 없습니다.
오래된:
나는 이것이 더 빠르고 이식성이 있다는 것을 알았습니다.
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
-exec
모든 디렉터리에 대해 그럴 필요는 없습니다. 단지 하나 의 sh
ell 프로세스와 하나 의 find
. 루트 디렉토리로 가서 확인하면 됩니다.set -- $glob
.hidden
cd
다음은 내 실행 결과의 예입니다 /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
또한 sed
맨 아래 항목을 사용하여 상위 50개 결과로 다듬었습니다. head
물론 더 빠르겠지만 필요한 경우 각 행을 다듬을 수도 있습니다.
...
159 /home/mikeserv/.config/hom...hhkdoolnlbekcfllmednbl/4.30_0/plugins
154 /home/mikeserv/.config/hom...odhpcledpamjachpmelml/1.3.11_0/js/ace
...
물론 조잡하지만 아이디어입니다. 내가 사용하는 또 다른 조악한 방법은 및 를 덤프 2>stderr
하는 것 입니다 . 루트 액세스 없이는 읽을 수 없는 디렉토리에 대한 권한 오류를 보는 것보다 더 깔끔합니다. 아마도 이를 로 지정해야 할 것입니다 .find
cd
2>/dev/null
find
좋습니다. 그래서 저는 쉘 글로브를 다음과 같이 수정했습니다:
for glob in ".[!.]*" "[!.]*" ; do
set -- $glob "$@" &&
[ -e "./$1" ] || shift
done
사실 이 작업을 수행하는 방법에 대해 질문하려고 했으나 질문 제목을 입력하자 사이트에서 다음을 가리켰습니다.추천 관련 질문보시다시피 스티븐은계량. 그래서 이것은 매우 편리합니다. 확실히, [^.],
잘 지원되면서도아니요!bang.
휴대용, Stephen의 의견에서 찾은 것을 사용해야 합니다 .
그럼에도 불구하고 단순히 숨겨진 파일을 가져오는 것만으로는 충분하지 않습니다. 그래서 set
position 에서 리터럴을 검색하지 않으려면 두 번 수행해야 합니다 $glob
. 그래도 성능에는 전혀 영향을 미치지 않는 것 같고 디렉터리의 모든 파일을 안정적으로 추가합니다.
답변2
GNU 도구 사용:
find / -xdev -type d -print0 |
while IFS= read -d '' dir; do
echo "$(find "$dir" -maxdepth 1 -print0 | grep -zc .) $dir"
done |
sort -rn |
head -50
이는 두 가지 find
명령을 사용합니다. 첫 번째는 디렉터리를 찾고 이를 while
각 디렉터리에 대한 다음 조회를 실행하는 루프에 전달합니다. 두 번째 항목은 첫 번째 수준의 모든 하위 파일/디렉토리를 grep
계산하는 동안 나열합니다. grep
동등한 항목이 없으므로 두 번째 조회와 함께 사용할 수 있습니다 . 이렇게 하면 개행 문자가 포함된 파일 이름이 두 번 계산되는 것을 방지할 수 있습니다(비록 및 no를 사용하더라도 큰 차이는 없습니다).-print0
wc
-z
wc
-print0
두 번째 결과는 find
인수에 배치되므로 echo
디렉토리 이름과 디렉토리 이름을 같은 줄에 쉽게 배치할 수 있습니다( $(..)
구조는 자동으로 후행 개행 문자를 자릅니다 grep
). 그런 다음 행이 숫자순으로 정렬되고 가장 큰 숫자 50개가 표시됩니다 head
.
여기에는 마운트 지점의 최상위 디렉터리도 포함됩니다. 이 문제를 해결하는 간단한 방법은 바인드 마운트를 사용한 다음 마운트된 디렉터리를 사용하는 것입니다. 이것을하기 위해:
sudo mount --bind / /mnt
보다 이식 가능한 솔루션은 각 디렉토리마다 다른 쉘 인스턴스를 사용하는 것입니다.여기):
find / -xdev -type d -exec sh -c '
echo "$(find "$0" | grep "^$0/[^/]*$" | wc -l) $0"' {} \; |
sort -rn |
head -50
예제 출력:
9225 /var/lib/dpkg/info
6322 /usr/share/qt4/doc/html
4927 /usr/share/man/man3
2301 /usr/share/man/man1
2097 /usr/share/doc
2097 /usr/bin
1863 /usr/lib/x86_64-linux-gnu
1679 /var/cache/apt/archives
1628 /usr/share/qt4/doc/src/images
1614 /usr/share/qt4/doc/html/images
1308 /usr/share/scilab/modules/overloading/macros
1083 /usr/src/linux-headers-3.13-1-common/include/linux
1071 /usr/src/linux-headers-3.13-1-amd64/include/config
847 /usr/include/qt4/QtGui
774 /usr/include/qt4/Qt
709 /usr/share/man/man8
616 /usr/lib
611 /usr/share/icons/oxygen/32x32/actions
608 /usr/share/icons/oxygen/22x22/actions
598 /usr/share/icons/oxygen/16x16/actions
579 /usr/share/bash-completion/completions
574 /usr/share/icons/oxygen/48x48/actions
570 /usr/share/vim/vim74/syntax
546 /usr/share/scilab/modules/m2sci/macros/sci_files
531 /usr/lib/i386-linux-gnu/wine/wine
530 /usr/lib/i386-linux-gnu/wine/wine/fakedlls
496 /etc/ssl/certs
457 /usr/share/mime/application
454 /usr/share/man/man2
450 /usr/include/qt4/QtCore
443 /usr/lib/python2.7
419 /usr/src/linux-headers-3.13-1-common/include/uapi/linux
413 /usr/share/fonts/X11/misc
413 /usr/include/linux
375 /usr/share/man/man5
374 /usr/share/lintian/overrides
372 /usr/share/cmake-2.8/Modules
370 /usr/share/fonts/X11/75dpi
370 /usr/share/fonts/X11/100dpi
356 /usr/share/icons/gnome/24x24/actions
356 /usr/share/icons/gnome/22x22/actions
356 /usr/share/icons/gnome/16x16/actions
353 /usr/share/icons/gnome/48x48/actions
353 /usr/share/icons/gnome/32x32/actions
341 /usr/lib/ghc/ghc-7.6.3
326 /usr/sbin
324 /usr/share/scilab/modules/compatibility_functions/macros
324 /usr/share/scilab/modules/cacsd/macros
320 /usr/share/terminfo/a
319 /usr/share/i18n/locales
답변3
KDirStat과 같은 것을 사용하면 어떨까요? 원래는 KDE용으로 작성되었지만 GNOME에서도 잘 작동합니다. GUI에서 파일/디렉토리 수와 각각의 사용법을 가장 잘 볼 수 있습니다.
답변4
이를 위해서는 zsh
glob 한정자가 필요합니다.
print -rC1 -- **/*(ND/nOe['(){REPLY=$#;} $REPLY/*(NDoN)'][1,50])
print -rC1 --
: s열의print
매개변수r
1
C
**/*
:recursive wildcard: 임의 개수의 하위 디렉터리에 있는 모든 파일(N...)
:glob 한정자는 glob 확장을 더욱 한정합니다.N
:N
울글롭. 일치하는 항목이 없어도 불평하지 않습니다.D
:D
오글롭. 또한 파일 숨기기를 고려하십시오.nOe[code]
: 평가액을 기준으로 역순으로 주문합니다O
.n
e
code
- 여기의 코드는 에 인수 수를 저장하는 익명 함수에 확장명을 전달하여
$REPLY
디렉터리의 파일 수를 설정합니다 .$REPLY/*(NDoN)
$REPLY
[1,50]
: 처음 50개만 반환됩니다.