在目录中列出包含子文件夹内容的文件并进行排序


9

我正在寻找列出目录的全部内容,包括子文件夹的内容,但按文件大小排序。到目前为止,我已经设法达到了列表和排序的目的,同时仍然可以递归使用ls -lhSRh很高兴,但对我来说绝对不是必需的,只要我可以获取文件大小即可)。我可能会忽略一些明显的问题,或者问一些不可能的事情,但是这里的任何建议将不胜感激。

Answers:


15

您可以使用find:

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)

太完美了!非常感谢,这正是我所需要的!
toms

3
我很高兴我的回答对您有所帮助。请考虑单击左侧的对勾标记,以将答案标记为已接受。谢谢。
pLumo

1
@RoVo赞成这个问题也很不错,因为考虑到您已经回答了这个问题,您可能会发现它有趣且有用。
terdon

确实的确如此,我现在就这样做了;-)
pLumo

@toms可以等待一段时间(也许一天左右)来接受答案,即使它和这个答案一样好。答案一旦被接受,就不可能再有另一个答案变得更好了。因此,很多人不会费心提出其他答案,因此我们没有机会看到他们找出更好的答案。
蒙迪·哈德

7

由于您没有指定特定的外壳,因此这是使用zsh的glob限定符和

setopt extendedglob

递归。然后例如:

  1. 递归列出普通文件:

    printf '%s\n' **/*(.)
  2. 递归列出纯文本文件,Ó rdered通过压痕大号 ength(即大小):

    printf '%s\n' **/*(.oL)
  3. 递归名单纯文本文件,Ø rdered由压痕尺寸:

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

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

如果还需要文件大小,则可以使用

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

4

globstar设置了shell选项后,您可以使用shell globbing:

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

不错的解决方案。与查找相比,它不包含隐藏文件,如何实现?
pLumo

@RoVo永远不要忘记这些–您只需要设置dotglobshell选项,请参阅我的最新答案。
甜点

除了考虑在使用sed之后printf "%s\0" **/* | xargs -0 sh -c 'for f; do [ -d "$f" ] || stat -c "%s %n" "$f"; done' sh | sort -n
删除

ls -lhSd **/*如果您不介意将目录作为列表的一部分,则可以使用。或者,如果没有目录名称都.在其中,和所有你想要的文件做的,你可以ll -hS **/*.*,或者类似的。
彼得·科德斯

把它变成了答案
Peter Cordes

3

如果没有zsh,仍然可以使用du+ sort

  1. 可读大小,包括目录的累积大小:

    du --apparent-size -ah0 . | sort -zh | xargs -0L1
    
  2. 仅文件(使用find):

    find . -type f -print0 |
      du --files0-from=- --apparent-size -ah0 |
      sort -zh |
      xargs -0L1
    

在这两种情况下,我选择用null终止线(-0-z-print0选项),是对全部有效文件名安全。


0

为了在不太大的目录树上进行快速交互使用shopt -s globstar确实非常好。一个glob不能根据类型过滤目录,但是如果将其与一起使用,ls -dls只会打印目录名称而不是内容。

假设您的ll别名包括-lh

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

会给您这样的输出(来自我的代码高尔夫球目录),但带有颜色突出显示(因此更容易查看目录)。请注意,按文件大小排序发生在子目录中。

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它来匹配所有文件。


使用GNU find

如果没有太多文件可容纳在一个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印刷品。与完美搭配使用du

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

du -sch **/* | sort -h如果您忘记了du-a选项,将为您提供以上输出。

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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.