如何让 find 命令打印出带有文件名的文件大小?

Posted

技术标签:

【中文标题】如何让 find 命令打印出带有文件名的文件大小?【英文标题】:How do I get the find command to print out the file size with the file name? 【发布时间】:2010-09-09 01:01:58 【问题描述】:

如果我发出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

【问题讨论】:

【参考方案1】:

只需使用磁盘使用命令 (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

【讨论】:

【参考方案2】:

使用 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',这应该是第一答案。它准确地回答了问题,解释了语法的含义,并提供了多种选择。 这应该被接受,因为它不会为每一行运行新命令,因此它比当前接受的来自 shyam 的命令要快得多 确实这应该是正确的答案。此外,find . -type f -printf '%k KB\t %p\n' 即首先打印文件大小,由于对齐,很可能会在格式方面得到更好的输出。【参考方案3】:

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

find . -name \*.ear -ls

这为您提供了正常“ls -l”格式的每个条目。或者,要获得您似乎正在寻找的特定输出,请执行以下操作:

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

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

【讨论】:

甚至不知道ls 选项,这在答案列表中应该比它高得多。【参考方案4】:

你可以试试 for 循环:

for i in `find . -iname "*.ear"`; do ls -lh $i; done

【讨论】:

【参考方案5】:

如果您需要获取总大小,这里有一个脚本建议

#!/bin/bash
totalSize=0

allSizes=`find . -type f -name *.ear -exec stat -c "%s"  \;`

for fileSize in $allSizes; do
    totalSize=`echo "$(($totalSize+$fileSize))"`
done
echo "Total size is $totalSize bytes"

【讨论】:

【参考方案6】:

尝试以下命令:

GNU stat:

find . -type f -name *.ear -exec stat -c "%n %s"  ';'

BSDstat:

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

但是stat 不是标准的,所以duwc 可能是更好的方法:

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

【讨论】:

【参考方案7】:
find . -name '*.ear' -exec du -h  \;

这只会给你文件大小,而不是所有不必要的东西。

【讨论】:

如果您需要以字节为单位的大小,wc 会更好地解决这个问题。 这只会给你文件大小, 不,这会给出磁盘使用情况,而不是文件大小。它们的注释相同。对于任何支持压缩的文件系统,此返回的值都是错误的。【参考方案8】:

这应该会为您提供所需的内容,包括格式(即首先是文件名,然后是大小):

find . -type f -iname "*.ear" -exec du -ah  \; | awk 'print $2"\t", $1'

示例输出(我使用-iname "*.php" 得到一些结果):

./plugins/bat/class.bat.inc.php  20K
./plugins/quotas/class.quotas.inc.php    8.0K
./plugins/dmraid/class.dmraid.inc.php    8.0K
./plugins/updatenotifier/class.updatenotifier.inc.php    4.0K
./index.php      4.0K
./config.php     12K
./includes/mb/class.hwsensors.inc.php    8.0K

【讨论】:

【参考方案9】:
find . -name "*.ear" -exec ls -l  \;

【讨论】:

【参考方案10】:

为什么不使用 du -a ?例如。

find . -name "*.ear" -exec du -a  \;

在 Mac 上工作

【讨论】:

基于du man page ` -a, --all write counts for all files, 而不仅仅是目录 ` 我想你想使用 -h ` -h, --human-readable print sizes以人类可读的格式(例如,1K 234M 2G)`【参考方案11】: $查找。 -name "test*" -exec du -sh \; 4.0K ./test1 0 ./test2 0 ./test3 0 ./test4 $

Scripter World reference

【讨论】:

【参考方案12】:
find . -name "*.ear" | xargs ls -sh

【讨论】:

【参考方案13】:

我在 Mac OS X 上遇到了这个问题,其中 find 命令不支持 -printf

我发现的一个解决方案,诚然依赖于“组”,所有文件都是“员工”是......

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

这会将 ls long 输出拆分为三个标记

    文本'staff'之前的东西 文件大小 文件名

然后输出标记2和3,即输出字节数,然后是文件名

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

【讨论】:

了解有用.. find 的 GNU 版本可通过自制软件使用brew install findutils 获得【参考方案14】:

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

% 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

【讨论】:

【参考方案15】:

您需要使用 -exec 或 -printf。 Printf 的工作原理是这样的:

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

-exec 更强大,可以让你执行任意命令——所以你可以使用 'ls' 或 'wc' 的版本来打印文件名和其他信息。 'man find' 将向您显示 printf 的可用参数,它可以做的不仅仅是文件大小。

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

【讨论】:

看起来您的示例更精确,但我似乎无法让该示例在 Solaris 10 上运行。 恐怕 Solaris find 根本不支持 -printf:jrwren.wrenfam.com/blog/2006/10/07/solaris-find-sucks cs.bgu.ac.il/~arik/usail/man/solaris/find.1.html 如果你介意的话,你可以安装 GNU find,否则你需要使用 exec 或 |按照其他人的建议。 +1 这看起来更干净。要格式化输出,我希望添加 column 命令。 find . -name *.ear -printf "%p %k KB\n" | column -t 这个答案比公认的答案更正确 -printf 选项在 OS X 中也不起作用。见***.com/questions/752818/…。【参考方案16】:
find . -name '*.ear' -exec ls -lh  \;

只是 jer.drab.org 回复中的 h 额外内容。节省精神上转换为 MB 的时间;)

【讨论】:

此版本将为每个文件执行“ls”进程。如果你有很多文件(比如超过一千个),你最好通过find . -name '*.ear' -exec ls -lh + \;(GNU 扩展)或find . -name '*.ear' -print0 | xargs -0 ls -lh 来优化它。如果您只对文件感兴趣,您也可以添加-type f(如果您希望目录本身不包含其内容,则将-d 添加到ls)。 您的答案不排除目录,因此您最终也会在目录上运行 ls,这显然不是正确的做法。 这是一种非常低效的做事方式——不幸的是 ash108 的 cmets 也不理想。最好使用 -printf 选项来查找。 dmazzoni 的回答效率更高,因为它避免了对每个文件执行 fork+exec(在我的机器上快 100 倍)。我不得不将 %k 更改为 %s。 @FaheemMitha:您可以添加 -type f 之类的选项来仅计算常规文件。 @FaheemMitha 简单的解决方案是find . -name "*.ear" -type f 用于文件。 -type d 适用于目录。【参考方案17】:

你可以试试这个:

find. -name *.ear -exec du  \;

这将为您提供以字节为单位的大小。但是 du 命令也接受参数 -k 代表 KB 和 -m 代表 MB。它会给你一个类似的输出

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

【讨论】:

以上是关于如何让 find 命令打印出带有文件名的文件大小?的主要内容,如果未能解决你的问题,请参考以下文章

linux下如何统计部分文件大小,有很多文件夹,还包含子文件件夹,统计出所有包含‘123’的文件的总大小

shell命令find

如何使用 find 命令从列表中查找所有带有扩展名的文件?

Linux命令-find命令

2.命令之乐

带有多个命令的 xargs