如何让find命令打印出文件名和文件大小?

166
如果我执行如下命令:

查找(find)命令的用法请参见维基百科

find . -name *.ear

它会打印出:

./dir1/dir2/earFile1.ear
./dir1/dir2/earFile2.ear
./dir1/dir3/earFile1.ear

我希望在命令行中“打印”名称和大小:

./dir1/dir2/earFile1.ear  5000 KB
./dir1/dir2/earFile2.ear  5400 KB
./dir1/dir3/earFile1.ear  5400 KB
17个回答

180
find . -name '*.ear' -exec ls -lh "{}" \;

只是从jer.drab.org的回复中多了一个h。这样可以节省将其转换为MB的时间,不用费脑子计算 ;)


19
此版本每个文件都将单独执行“ls”进程。如果您有很多文件(比如一千个以上),最好通过以下方式进行优化: find . -name '*.ear' -exec ls -lh {} + \;(GNU扩展) 或者 find . -name '*.ear' -print0 | xargs -0 ls -lh。如果您只对文件感兴趣(或者希望包含目录本身而不是其内容),还可以添加-type f选项(如果要包含目录但不包含其内容,则可以添加-d到ls命令)。 - ash108
2
你的答案没有排除目录,因此你最终会在目录上运行ls命令,这显然不是正确的做法。 - Faheem Mitha
3
这是一种非常低效的做事方式 - 不幸的是,ash108的评论也不理想。最好使用“-printf”选项来查找。 - oskarpearson
1
dmazzoni的答案更有效率,因为它避免了在每个文件上进行fork+exec(在我的机器上快100倍)。我不得不将%k更改为%s。@FaheemMitha:您可以添加选项,如“-type f”仅计算常规文件。 - Mr Fooz
@FaheemMitha 简单的解决方案是 find . -name "*.ear" -type f 用于查找文件。-type d 用于查找目录。 - fIwJlxSzApHEZIl
显示剩余2条评论

149

你需要使用-exec或-printf。Printf的用法如下:

find . -name *.ear -printf "%p %k KB\n"

-exec更加强大,允许您执行任意命令,因此您可以使用“ls”或“wc”的一个版本来打印出文件名以及其他信息。“man find”将向您展示可用的printf参数,它可以做比仅仅打印文件大小更多的事情。

[编辑] -printf不在官方POSIX标准中,请检查您的版本是否支持。然而,大多数现代系统将使用GNU find或类似扩展版本,因此很有可能已经实现了。


1
很抱歉,Solaris的查找并不支持-printf:http://jrwren.wrenfam.com/blog/2006/10/07/solaris-find-sucks/http://www.cs.bgu.ac.il/~arik/usail/man/solaris/find.1.html如果您愿意安装GNU find,则可以使用它。否则,您需要使用exec或|,如其他人所建议的那样。 - Leigh Caldwell
1
+1 这看起来更加清晰。为了格式化输出,我更喜欢添加 column 命令。find . -name *.ear -printf "%p %k KB\n" | column -t - Amol
1
这个答案比被采纳的答案更正确。 - menacingly
3
-printf选项在OS X中也不起作用。请参见https://dev59.com/uHRB5IYBdhLWcg3wAjJH。 - abeboparebop
在最近的Ubuntu上运行得非常好! - Gringo Suave
显示剩余3条评论

53

一个简单的解决方案是使用find命令中的-ls选项:

find . -name \*.ear -ls

这将为您提供正常“ls -l”格式中的每个条目。或者,为了获得您似乎正在寻找的特定输出,可以使用以下命令:

find . -name \*.ear -printf "%p\t%k KB\n"

这将为您提供文件名,后跟以KB为单位的大小。

1
甚至不知道有一个 ls 选项,这应该比它现在排名更靠前。 - Hashim Aziz

31
使用GNU find,我认为这就是您想要的。它可以找到所有真实文件而不是目录(-type f),并为每个文件打印文件名(%p),一个制表符(\t),以千字节为单位的大小(%k),后缀“ KB”,然后是一个换行符(\n)。
find . -type f -printf '%p\t%k KB\n'

如果 printf 命令的格式不符合您的要求,您可以使用 exec 命令,后跟您想要在每个文件上执行的命令。 使用 {} 表示文件名,并用分号 (;) 终止命令。 在大多数 shell 中,这三个字符都应该用反斜杠进行转义。
以下是一个简单的解决方案,它使用 "ls -lh" 查找并打印它们,这将以人类可读的形式显示大小(k 表示千字节,M 表示兆字节):
find . -type f -exec ls -lh \{\} \;

作为另一种选择,“wc -c”将打印文件中字符(字节)的数量:
find . -type f -exec wc -c \{\} \;

1
除了在示例中省略了“-name '*.ear'”之外,这应该是第一答案。它精确回答了问题,解释了语法的含义,并提供了多种替代方案。 - OsakaWebbie
1
这应该被接受为答案,因为它不会为每一行运行新的命令,因此比目前被接受的更快。 - jirislav
1
实际上,这应该是正确的答案。 另外,find . -type f -printf '%k KB\t %p\n',即首先打印文件大小,由于对齐,这很可能会产生更好的格式输出。 - myradio

9
find . -name '*.ear' -exec du -h {} \;

这将只给您文件大小,而不是所有不必要的信息。


如果你需要以字节为单位的大小,那么wc更适合这个任务。 - Alex
1
这只会给你磁盘使用量,而不是文件大小。它们并不相同。对于任何支持压缩的文件系统,这个返回值都将是错误的。 - Andrew Henle

7

只需使用磁盘使用率命令(du -h)列出匹配该模式(-name '*.ear)的文件(-type f),并按易读的文件大小排序(sort -h):

find . -type f -name '*.ear' -exec du -h {} \; | sort -h

输出

5.0k  ./dir1/dir2/earFile1.ear
5.4k  ./dir1/dir2/earFile2.ear
5.4k  ./dir1/dir3/earFile1.ear

4

Awk可以修正输出,以给出问题者所要求的内容。在我的Solaris 10系统上,find -ls打印KB大小作为第二个字段,因此:

awk '{print $7}' find . -type f -ls

% find . -name '*.ear' -ls | awk '{print $2, $11}'
5400 ./dir1/dir2/earFile2.ear
5400 ./dir1/dir2/earFile3.ear
5400 ./dir1/dir2/earFile1.ear

否则,请使用-exec ls -lh并从输出中选取大小字段。 同样在Solaris 10上:
% find . -name '*.ear' -exec ls -lh {} \; | awk '{print $5, $9}'
5.3M ./dir1/dir2/earFile2.ear
5.3M ./dir1/dir2/earFile3.ear
5.3M ./dir1/dir2/earFile1.ear

4
请尝试以下命令:
GNU stat 命令:
find . -type f -name *.ear -exec stat -c "%n %s" {} ';'

BSD stat:

find . -type f -name *.ear -exec stat -f "%N %z" {} ';'

然而,stat 不是标准命令,因此 duwc 可能是更好的选择:

find . -type f -name *.ear -exec sh -c 'echo "{} $(wc -c < {})"' ';'

3

在 Mac OS X 上,find 命令不支持 -printf 选项,这让我很苦恼。

最终我找到了一个解决方案,虽然它依赖于所有文件的 'group' 均为 'staff',具体操作如下:

ls -l -R | sed 's/\(.*\)staff *\([0-9]*\)..............\(.*\)/\2 \3/'

这将把ls命令的长格式输出分成三个部分:

  1. 'staff'文本之前的内容
  2. 文件大小
  3. 文件名

然后输出第2和第3个部分,即输出字节数和文件名。

8071 sections.php
54681 services.php
37961 style.css
13260 thumb.php
70951 workshops.php

1
有用的知识... GNU 版本的 find 可以通过 homebrew 安装,使用 brew install findutils 命令。 - mwfearnley

3
为什么不使用 du -a 呢?例如:
find . -name "*.ear" -exec du -a {} \;

适用于Mac


1
基于 du 命令手册-a, --all 输出所有文件的计数,而不仅仅是目录我认为你想使用 -h-h, --human-readable 以人类可读的格式打印文件大小(例如,1K 234M 2G) - Craig
1
因为这会打印磁盘使用情况,而不是文件大小。 - DanielSmedegaardBuus

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接