我想列出目录的全部内容,包括子文件夹的内容,但按文件大小排序。到目前为止,我已经设法做到了列出和排序,同时仍然使用递归ls -lhSR
(h
有这个功能很好,但对我来说绝对不是必需的,只要我能得到文件大小)。我可能忽略了一些显而易见的事情,或者问了一些不可能的事情,但任何建议都会非常感激。
答案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
进行递归。例如:
递归列出纯文本文件:
printf '%s\n' **/*(.)
递归列出纯文本文件,o订购者在折痕大号长度(即尺寸):
printf '%s\n' **/*(.oL)
递归列出纯文本文件,哦订购者德折痕尺寸:
printf '%s\n' **/*(.OL)
递归列出纯文本文件,按大小递减顺序排列,并选择前 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
如果您尝试使用太多文件,您将收到“参数列表太长”错误。要解决该问题,您可以使用printf
和xargs
:
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 -d
则ls
只会打印目录名称,而不是内容。
假设您的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 -h
prints)的数字进行排序。它非常适合与 一起使用du
。
我经常使用du -sch * | sort -h
、 或*/
来获取目录。
du -sch **/* | sort -h
du
如果您忘记了有一个选项,将会给您上述输出-a
。
(我只是花时间查找它,因为我正在发布一个答案。对于交互式使用,我可能只会使用du -sch **/*
。