Linux Shell:列出按文件数排序的目录(包括在子目录中)

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6918057/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-05 05:25:33  来源:igfitidea点击:

Shell: list directories ordered by file count (including in subdirectories)

linuxunixshellcommand-line

提问by Richard Inglis

I've nearly reached my limit for the permitted number of files in my Linux home directory, and I'm curious about where all the files are.

我几乎达到了 Linux 主目录中允许的文件数限制,我很好奇所有文件的位置。

In any directory I can use for example find . -type f | wc -lto show a count of how many files are in that directory and in its subdirectories, but what I'd like is to be able to generate a complete list of all subdirectories (and sub-subdirectories etc) each with a countof all files contained in it and itssubdirectories - if possible ranked by count, descending.

在任何目录中,我可以使用例如find . -type f | wc -l显示该目录及其子目录中有多少文件的计数,但我想要的是能够生成所有子目录(和子子目录等)的完整列表每一个计数的所有文件包含在它和它的子目录-如果有可能通过排名数,降。

Eg if my file structure looks like this:

例如,如果我的文件结构如下所示:

Home/
  file1.txt
  file2.txt
  Docs/
    file3.txt
    Notes/
      file4.txt
      file5.txt
    Queries/
      file6.txt
  Photos/
    file7.jpg

The output would be something like this:

输出将是这样的:

7  Home
4  Home/Docs
2  Home/Docs/Notes
1  Home/Docs/Queries
1  Home/Photos

Any suggestions greatly appreciated. (Also a quick explanation of the answer, so I can learn from this!). Thanks.

任何建议都非常感谢。(也是对答案的快速解释,所以我可以从中学习!)。谢谢。

采纳答案by glenn Hymanman

countFiles () {
    # call the recursive function, throw away stdout and send stderr to stdout
    # then sort numerically
    countFiles_rec "" 2>&1 >/dev/null | sort -nr
}

countFiles_rec () {
    local -i nfiles 
    dir=""

    # count the number of files in this directory only
    nfiles=$(find "$dir" -mindepth 1 -maxdepth 1 -type f -print | wc -l)

    # loop over the subdirectories of this directory
    while IFS= read -r subdir; do

        # invoke the recursive function for each one 
        # save the output in the positional parameters
        set -- $(countFiles_rec "$subdir")

        # accumulate the number of files found under the subdirectory
        (( nfiles +=  ))

    done < <(find "$dir" -mindepth 1 -maxdepth 1 -type d -print)

    # print the number of files here, to both stdout and stderr
    printf "%d %s\n" $nfiles "$dir" | tee /dev/stderr
}


countFiles Home

produces

产生

7 Home
4 Home/Docs
2 Home/Docs/Notes
1 Home/Photos
1 Home/Docs/Queries

回答by sagi

This should work:

这应该有效:

find ~ -type d -exec sh -c "fc=$(find '{}' -type f | wc -l); echo -e \"$fc\t{}\"" \; | sort -nr

Explanation: In the command above will run "find ~ -type d" to find all the sub-directories the home-directory. For each of them, it runs a short shell script that finds the total number of files in that sub-directory (using the "find $dir -type f | wc -l" command that you already know), and will echo the number followed by the directory name. The sort command then runs to sort by the total number of files, in a descending order.

说明:在上面的命令中会运行“find ~ -type d”来查找home-directory的所有子目录。对于它们中的每一个,它都会运行一个简短的 shell 脚本来查找该子目录中的文件总数(使用您已经知道的“find $dir -type f | wc -l”命令),并将回显该数字后跟目录名称。然后运行 ​​sort 命令以按文件总数降序排序。

This is not the most efficient solution (you end up scanning the same directory many times), but I am not sure you can do much better with a one liner :-)

这不是最有效的解决方案(您最终会多次扫描同一个目录),但我不确定您是否可以使用一个班轮做得更好:-)

回答by wjb

simpler and more efficient:

更简单、更高效:

find ~ -type f -exec dirname {} \; | sort | uniq -c | sort -nr

回答by ajtrichards

I use the following command

我使用以下命令

find . -xdev -type f | cut -d "/" -f 2 | sort | uniq -c | sort -n

find . -xdev -type f | cut -d "/" -f 2 | sort | uniq -c | sort -n

Which produces something like:

这会产生类似的东西:

[root@ip-***-***-***-*** /]# find . -xdev -type f | cut -d "/" -f 2 | sort | uniq -c | sort -n
      1 .autofsck
      1 stat-nginx-access
      1 stat-nginx-error
      2 tmp
     14 boot
     88 bin
    163 sbin
    291 lib64
    597 etc
    841 opt
   1169 root
   2900 lib
   7634 home
  42479 usr
  80964 var

回答by loupiote

find . -type d -exec sh -c '(echo -n "{} "; ls {} | wc -l)' \; | sort -n -k 2

This is pretty efficient.

这是相当有效的。

It will display the counts in ascending order (i.e. largest at the end). To get it is descending order, add the "-r" option to "sort".

它将按升序显示计数(即末尾最大)。要得到它是降序,将“-r”选项添加到“排序”。

If you run this command in the "/" directory, it will scan the entire filesystem and tell you what are the directories that contain the most files and sub-directories. It's a good way to see where all your inodes are being used.

如果您在“/”目录中运行此命令,它将扫描整个文件系统并告诉您包含最多文件和子目录的目录是什么。这是查看所有 inode 正在使用的位置的好方法。

Note: this will not work for directories that contain spaces, but you could modify it to work in that case, if it's a problem for you.

注意:这不适用于包含空格的目录,但您可以修改它以在这种情况下工作,如果这对您来说是个问题。

回答by Henrik Hedemann

If however you are fine with the non cumulative solution by using dirname (see answer of wjb) then by far more efficient is:

但是,如果您对使用 dirname 的非累积解决方案感到满意(请参阅 wjb 的答案),那么效率更高的是:

find ~ -type f -print0 | xargs -0 dirname | sort | uniq -c | sort -n

Note that this does not display empty dirs. For that you may do find ~ -type d -empty if your version of find supports it.

请注意,这不会显示空目录。为此,如果您的 find 版本支持,您可能会 find ~ -type d -empty。

回答by osexp2003

See following example: sort by column 2 reversely. Use sort -k 2 -r. -k 2 means sort with column 2 (space separated), -r means reverse.

请参见以下示例:按第 2 列反向排序。使用sort -k 2 -r. -k 2 表示按第 2 列(空格分隔)排序,-r 表示反向。

# ls -lF /mnt/sda1/var/lib/docker/165536.165536/aufs/mnt/ | sort -k 2 -r
total 972
drwxr-xr-x   65 165536   165536        4096 Jun  5 12:23 ad45ea3c6a03aa958adaa4d5ad6fc25d31778961266972a69291d3664e3f4d37/
drwxr-xr-x   19 165536   165536        4096 Jun  6 06:46 7fa7f957669da82a8750e432f034be6f0a9a7f5afc0a242bb00eb8024f77d683/
drwxr-xr-x    2 165536   165536        4096 May  8 02:20 49e067ffea226cfebc8b95410e90c4bad6a0e9bc711562dd5f98b7d755fe6efb/
drwxr-xr-x    2 165536   165536        4096 May  8 01:19 45ec026dd49c188c68b55dcf98fda27d1f9dd32f825035d94849b91c433b6dd3/
drwxr-xr-x    2 165536   165536        4096 Mar 13 06:08 0d6e95d4605ab34d1454de99e38af59a267960999f408f720d0299ef8d90046e/
drwxr-xr-x    2 165536   165536        4096 Mar 13 02:25 e9b252980cd573c78065e8bfe1d22f01b7ba761cc63d3dbad284f5d31379865a/
drwxr-xr-x    2 165536   165536        4096 Mar 13 02:24 f4aa333b9c208b18faf00b00da150b242a7a601693197c1f1ca78b9ab2403409/
drwxr-xr-x    2 165536   165536        4096 Mar 13 02:24 3946669d530695da2837b2b5ed43afa11addc25232b29cc085a19c769425b36b/
drwxr-xr-x    2 165536   165536        4096 Mar 11 11:11 44293f77f63806a58d9b97c3c9f7f1397b6f0935e236250e24c9af4a73b3e35b/