Làm cách nào tôi có thể sử dụng find
để tạo danh sách các thư mục chứa số lượng tệp nhiều nhất. Tôi muốn danh sách từ cao nhất đến thấp nhất. Tôi chỉ muốn danh sách đi sâu 1 cấp và tôi thường chạy lệnh này từ đầu hệ thống tệp của mình, tức là /
.
Làm cách nào tôi có thể sử dụng find
để tạo danh sách các thư mục chứa số lượng tệp nhiều nhất. Tôi muốn danh sách từ cao nhất đến thấp nhất. Tôi chỉ muốn danh sách đi sâu 1 cấp và tôi thường chạy lệnh này từ đầu hệ thống tệp của mình, tức là /
.
Câu trả lời:
Sử dụng các công cụ 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
Cái này dùng hai find
lệnh. Đầu tiên tìm thấy các thư mục và dẫn chúng đến một while
vòng lặp chạy tìm kiếm tiếp theo cho mỗi thư mục. Thứ hai liệt kê tất cả các tập tin / thư mục con ở cấp độ đầu tiên trong khi grep
đếm chúng. Các grep
phép -print0
để được sử dụng với tìm thứ hai kể từ khi wc
không có một -z
tương đương. Điều này ngăn tên tập tin với một dòng mới được tính hai lần (mặc dù sử dụng wc
và -print0
không tạo ra nhiều khác biệt).
Kết quả của lần thứ hai find
được đặt trong đối số để echo
nó và tên thư mục có thể dễ dàng được đặt trên cùng một dòng ( $(..)
cấu trúc sẽ tự động cắt đường mới ở cuối grep
). Các dòng sau đó được sắp xếp theo số và 50 số lớn nhất được hiển thị với head
.
Lưu ý rằng điều này cũng sẽ bao gồm các thư mục cấp cao nhất của các điểm gắn kết. Một cách đơn giản để giải quyết vấn đề này là sử dụng mount mount và sau đó sử dụng thư mục của mount. Để làm điều này:
sudo mount --bind / /mnt
Một giải pháp di động hơn sử dụng một thể hiện shell khác nhau cho mỗi thư mục (cũng được trả lời ở đây ):
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
du --inodes -S | sort -rh | sed -n \
'1,50{/^.\{71\}/s/^\(.\{30\}\).*\(.\{37\}\)$/\1...\2/;p}'
Và nếu bạn muốn ở trong cùng một hệ thống tập tin bạn làm:
du --inodes -xS
Dưới đây là một số ví dụ đầu ra:
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
Một số người đề cập rằng họ không có coreutils cập nhật và tùy chọn --inodes không có sẵn cho họ. Vì vậy, đây là 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
Điều này mang lại cho tôi khá nhiều kết quả giống hệt với du
lệnh:
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
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:
Tôi nghĩ rằng include
điều này chỉ phụ thuộc vào thư mục mà chương trình nhìn vào đầu tiên - bởi vì chúng là các tệp giống nhau và được liên kết cứng. Kinda như điều trên. Tôi có thể sai về điều đó mặc dù - và tôi hoan nghênh sự điều chỉnh ...
Phương pháp cơ bản cho vấn đề này là tôi thay thế mỗi ls
tên tệp bằng tên thư mục chứa trong sed.
Tiếp theo từ đó ... Chà, bản thân tôi hơi mờ. Tôi khá chắc chắn rằng nó đếm chính xác các tệp, như bạn có thể thấy ở đây:
% _ls_i ~/test
> 100 /home/mikeserv/test/realdir
> 2 /home/mikeserv/test
> 1 /home/mikeserv/test/linkdir
% du --version
> du (GNU coreutils) 8.22
Tạo một thư mục thử nghiệm:
% mkdir ~/test ; cd ~/test
% du --inodes -S
> 1 .
Một số thư mục trẻ em:
% mkdir ./realdir ./linkdir
% du --inodes -S
> 1 ./realdir
> 1 ./linkdir
> 1 .
Tạo một số tệp:
% printf 'touch ./realdir/file%s\n' `seq 1 100` | . /dev/stdin
% du --inodes -S
> 101 ./realdir
> 1 ./linkdir
> 1 .
Một số liên kết cứng:
% printf 'n="%s" ; ln ./realdir/file$n ./linkdir/link$n\n' `seq 1 100` |
. /dev/stdin
% du --inodes -S
> 101 ./realdir
> 1 ./linkdir
> 1 .
Nhìn vào các liên kết cứng:
% cd ./linkdir
% du --inodes -S
> 101
% cd ../realdir
% du --inodes -S
> 101
Họ được tính một mình, nhưng đi lên một thư mục ...
% cd ..
% du --inodes -S
> 101 ./realdir
> 1 ./linkdir
> 1 .
Sau đó, tôi chạy tập lệnh đã chạy của tôi từ bên dưới và:
> 100 /home/mikeserv/test/realdir
> 100 /home/mikeserv/test/linkdir
> 2 /home/mikeserv/test
Và Graeme:
> 101 ./realdir
> 101 ./linkdir
> 3 ./
Vì vậy, tôi nghĩ rằng điều này cho thấy cách duy nhất để đếm inodes là inode. Và bởi vì đếm các tệp có nghĩa là đếm các nút, bạn không thể đếm gấp đôi các nút - để đếm các tệp chính xác, các nút không thể được đếm nhiều lần.
Tôi thấy cái này nhanh hơn và nó có thể mang theo được:
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ó không phải -exec
cho mọi thư mục - nó chỉ sử dụng một sh
quá trình ell và một find
. Tôi phải có set -- $glob
quyền bao gồm .hidden
các tệp và tất cả các tệp khác, nhưng nó rất gần và rất nhanh. Bạn sẽ chỉ cần cd
vào bất cứ thứ gì thư mục gốc của bạn sẽ được kiểm tra và tắt đi.
Đây là một mẫu đầu ra của tôi chạy từ /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
Tôi cũng sử dụng sed
ở dưới cùng để cắt nó thành 50 kết quả hàng đầu. head
tất nhiên sẽ nhanh hơn, nhưng tôi cũng cắt từng dòng nếu cần thiết:
...
159 /home/mikeserv/.config/hom...hhkdoolnlbekcfllmednbl/4.30_0/plugins
154 /home/mikeserv/.config/hom...odhpcledpamjachpmelml/1.3.11_0/js/ace
...
Đó là thô thiển, thừa nhận, nhưng đó là một suy nghĩ. Một thiết bị thô khác tôi sử dụng là bán phá giá 2>stderr
cho cả hai find
và cd
vào 2>/dev/null
. Nó chỉ sạch hơn là nhìn vào các lỗi cấp phép cho các thư mục mà tôi không thể đọc mà không có quyền truy cập root - có lẽ tôi nên chỉ định điều đó find
. Vâng, đó là một công việc đang tiến triển.
Ok, vì vậy tôi đã sửa chữa các khối vỏ như thế này:
for glob in ".[!.]*" "[!.]*" ; do
set -- $glob "$@" &&
[ -e "./$1" ] || shift
done
Tôi thực sự sẽ hỏi một câu hỏi về cách nó có thể được thực hiện, nhưng khi tôi đang gõ tiêu đề câu hỏi, trang web chỉ cho tôi một câu hỏi liên quan được đề xuất trong đó, lo và kìa, Stephane đã cân nhắc . Vì vậy, đó là thuận tiện. Rõ ràng [^.],
trong khi được hỗ trợ tốt, không phải là di động và bạn phải sử dụng!bang.
Tôi thấy rằng trong nhận xét của Stephane ở đó.
Dù sao, chỉ cần kéo vào các tập tin ẩn là không đủ, rõ ràng. Vì vậy, tôi phải set
hai lần để tránh tìm kiếm vị trí cho nghĩa đen $glob
. Tuy nhiên, nó dường như không ảnh hưởng đến hiệu suất, và nó đáng tin cậy thêm mọi tệp trong thư mục.
ls -i
và ... tôi đoán ... có lẽ grep
... có lẽ - tốt, bạn đang sử dụng -xdev,
đó là một sự khởi đầu ... uniq
và sort
?
du
nào bạn đang chạy? My du
không có --inodes
lựa chọn.