列出目录中的文件(包括子文件夹的内容)并进行排序

列出目录中的文件(包括子文件夹的内容)并进行排序

我想列出目录的全部内容,包括子文件夹的内容,但按文件大小排序。到目前为止,我已经设法做到了列出和排序,同时仍然使用递归ls -lhSRh有这个功能很好,但对我来说绝对不是必需的,只要我能得到文件大小)。我可能忽略了一些显而易见的事情,或者问了一些不可能的事情,但任何建议都会非常感激。

答案1

您可以使用查找:

find . -type f -printf "%s %P\n" | sort -n

可选:要将字节值转换为人类可读的格式,请添加以下内容:

| numfmt --to=iec-i --field=1

解释:

 find in current directory (.) all files (-type f) 

 -printf: suppress normal output and print the following:
     %s - size in bytes
     %P - path to file
     \n - new line

 | sort -n: sort the result (-n = numeric)

答案2

由于你没有指定特定的 shell,因此可以使用 zsh 的 glob 限定符进行替代

setopt extendedglob

进行递归。例如:

  1. 递归列出纯文本文件:

    printf '%s\n' **/*(.)
    
  2. 递归列出纯文本文件,o订购者折痕大号长度(即尺寸):

    printf '%s\n' **/*(.oL)
    
  3. 递归列出纯文本文件,订购者折痕尺寸:

    printf '%s\n' **/*(.OL)
    
  4. 递归列出纯文本文件,按大小递减顺序排列,并选择前 3 个结果:

    printf '%s\n' **/*(.OL[1,3])
    

如果你还想要文件大小,那么你可以使用

du -hb **/*(.OL[1,3])

答案3

设置 shell 选项后,globstar您可以使用 shell 通配符:

shopt -s globstar         # don’t match hidden files
shopt -s globstar dotglob # match hidden files
stat -c"%s %n" **/* | sort -n

如果您尝试使用太多文件,您将收到“参数列表太长”错误。要解决该问题,您可以使用printfxargs

printf "%s\0" **/* | xargs -0 stat -c"%s %n" | sort -n

我刚刚意识到这也会打印目录(大小为 4096 字节)——如果您不想要这样,请改用这个:

stat -c"%A %s %n" **/* | sed '/^d/d;s/\S* //' | sort -n
printf "%s\0" **/* | xargs -0 stat -c"%A %s %n" | sed '/^d/d;s/\S* //' | sort -n

示例运行

$ tree
.
├── edits.png
├── makescript
├── new
│   └── edits.png
└── test
    └── 1.png

2 directories, 4 files
$ stat -c"%s %n" **/* | sort -n
0 test/1.png
43 makescript
2160 edits.png
2160 new/edits.png
4096 new
4096 test
$ stat -c"%A %s %n" **/* | sed '/^d/d;s/\S* //' | sort -n
0 test/1.png
43 makescript
2160 edits.png
2160 new/edits.png

答案4

实现快速交互使用在不太大的目录树上,shopt -s globstar非常棒。 glob 无法根据类型过滤目录,但如果您使用它,ls -dls只会打印目录名称,而不是内容。

假设您的ll别名包括-lh

  # with  shopt -s globstar   in your .bashrc
ll -rSd **/*

将为您提供类似这样的输出(来自我的 code-golf 目录),但带有颜色突出显示(因此更容易看到目录)。请注意,按文件大小排序发生在子目录中。

drwxr-xr-x 1 peter peter   70 Jun  8 07:56 casexchg
...
drwxr-xr-x 1 peter peter  342 Mar 13 18:47 parity-party
-rw-r--r-- 1 peter peter  387 Jul 29  2017 likely.cpp
-rw-r--r-- 1 peter peter  416 Aug 31  2017 true-binary.asm~
-rw-r--r-- 1 peter peter  447 Feb 23 20:14 weight-of-zero.asm
...
-rw-r--r-- 1 peter peter 6.4K Jun  1  2017 string-exponential.asm
-rwxr-xr-x 1 peter peter 6.7K Aug 31  2017 true-binary
-rwxr-xr-x 1 peter peter 6.8K Sep 17  2017 dizzy-integer
-rw-r--r-- 1 peter peter 7.5K Jul 24  2017 fibonacci/fibonacci-1G.v3-working-32b-stack-except-output.asm
-rw-r--r-- 1 peter peter 8.4K Jul 25  2017 fibonacci/perf.32bit-pop-114limb.sub-cmc.1G~
-rw-r--r-- 1 peter peter 8.4K Jul 25  2017 fibonacci/perf.32bit-pop-114limb.sub-cmc.1G
-rwxr-xr-x 1 peter peter 8.4K May 19 04:29 a.out
-rw-r--r-- 1 peter peter 8.9K Jul 25  2017 fibonacci/perf.python-xnor-2n
-rw-r--r-- 1 peter peter 9.5K Jul 26  2017 fibonacci/fibonacci-1G-performance.asm
-rwxr-xr-x 1 peter peter 9.6K Apr 12 23:25 empty-args
-rw-r--r-- 1 peter peter 9.7K Dec 18 17:00 bubblesort.asm
-rwxr-xr-x 1 peter peter 9.9K Feb  6 23:34 parity-party/a.out
-rw-r--r-- 1 peter peter 9.9K Jul 25  2017 fibonacci/fibonacci-1G-performance.asm~
...

您可以通过管道过滤目录grep -v '^d'

如果你的文件名有模式,你有时可以使用只匹配文件而不匹配目录的 glob。例如ll -rSd **/*.jpg**/*.*即使你的目录名中没有一个包含模式.,你也能找到你想要的所有文件。

(对于具有 DOS 背景的人来说:Unix 上没有什么神奇之处*.*。它只匹配包含文字点的任何目录条目。但除了可执行文件和有时的文本文件之外,通常会为文件名提供扩展名。)

@dessert 指出你需要shopt -s dotglob匹配全部文件。


使用 GNUfind

如果文件数量不是太多而无法放在一个ls命令行中,find -exec ls {} +则会将它们全部放在ls可以对它们进行排序的命令行上。

find -not -type d -exec ls --color -lrSh {} +

使用-not -type d而不是-type f避免忽略符号链接,命名管道,套接字,设备文件以及目录中存在的任何其他内容。


du

du -ach | sort -h
....
4.0K    x86-modedetect-polyglot.o
8.0K    ascii-compress-base.asm
8.0K    dizzy-integer
8.0K    stopwatch-rdtsc.asm
8.0K    string-exponential.asm
8.0K    true-binary
12K     a.out
12K     bubblesort.asm
12K     casexchg
12K     empty-args
100K    parity-party
220K    fibonacci
628K    total

现在目录名称已排序到列表中,其中包含其所有内容的总和,但仍包含单个文件。

sort -h,又名--human-numeric-sort,对带有大小后缀(如du -hprints)的数字进行排序。它非常适合与 一起使用du

我经常使用du -sch * | sort -h、 或*/来获取目录。

du -sch **/* | sort -hdu如果您忘记了有一个选项,将会给您上述输出-a

(我只是花时间查找它,因为我正在发布一个答案。对于交互式使用,我可能只会使用du -sch **/*

相关内容