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

发布于 2024-11-27 08:22:14 字数 570 浏览 2 评论 0原文

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

在任何目录中,我可以使用例如 find 。 -类型 f | wc -l 显示该目录及其子目录中有多少文件的计数,但我希望能够生成每个子目录(以及子子目录等)的完整列表包含其中及其子目录中包含的所有文件的计数 - 如果可能的话按计数降序排列。

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

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

输出将如下所示:

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

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

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.

In any directory I can use for example find . -type f | wc -l to 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 count of all files contained in it and its subdirectories - if possible ranked by count, descending.

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

卸妝后依然美 2024-12-04 08:22:14

我使用以下命令

find 。 -xdev -类型 f |切-d“/”-f 2 |排序| uniq-c| sort -n

会产生类似以下内容的内容:

[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

I use the following command

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
嘿嘿嘿 2024-12-04 08:22:14

这应该有效:

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

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

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

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.

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 :-)

淡紫姑娘! 2024-12-04 08:22:14
countFiles () {
    # call the recursive function, throw away stdout and send stderr to stdout
    # then sort numerically
    countFiles_rec "$1" 2>&1 >/dev/null | sort -nr
}

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

    # 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 += $1 ))

    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

产生

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

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

    # 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 += $1 ))

    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
青朷 2024-12-04 08:22:14

更简单、更高效:

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

simpler and more efficient:

find ~ -type f -exec dirname {} \; | sort | uniq -c | sort -nr
救星 2024-12-04 08:22:14
find . -type d -exec sh -c '(echo -n "{} "; ls {} | wc -l)' \; | sort -n -k 2

这非常有效。

它将按升序显示计数(即最大的在最后)。要使其按降序排列,请在“排序”中添加“-r”选项。

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

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

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".

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.

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.

等待圉鍢 2024-12-04 08:22:14

请参阅以下示例:按第 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/

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.

# 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/
〗斷ホ乔殘χμё〖 2024-12-04 08:22:14

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

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

请注意,这不会显示空目录。为此你可以这样做
查找 ~ -type d -empty
如果您的 find 版本支持它。

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

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文