如何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
杜德莫
% 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
还有格雷姆的:
> 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
.它比查看没有 root 访问权限就无法读取的目录的权限错误更干净 - 也许我应该将其指定为find
.嗯,这是一项正在进行的工作。
好的,所以我确实修复了 shell glob,如下所示:
for glob in ".[!.]*" "[!.]*" ; do
set -- $glob "$@" &&
[ -e "./$1" ] || shift
done
我实际上是想问一个关于如何做到这一点的问题,但是当我输入问题标题时,该网站向我指出了一个建议的相关问题在那里,你瞧,斯蒂芬已经称重。所以这很方便。显然,[^.],
虽然得到了良好的支持,但不是便携式,你必须使用!bang.
我在斯蒂芬的评论中发现的。
不管怎样,显然,仅仅拉入隐藏文件是不够的。所以我必须set
两次才能避免在位置中搜索字面量$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
更可移植的解决方案为每个目录使用不同的 shell 实例(也回答了这里):
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
**/*
:递归通配:任意数量子目录中的任何文件(N...)
: glob 限定符进一步限定 glob 扩展N
:N
乌尔格洛布。如果没有匹配,不会抱怨。D
:D
otglob。还要考虑隐藏文件nOe[code]
:根据的估价进行反向O
订单。n
e
code
- 这里的代码通过将 的扩展传递给将其参数数量存储在 中的匿名函数来
$REPLY
设置目录中的文件数。$REPLY/*(NDoN)
$REPLY
[1,50]
: 只返回前 50 个。