Unix 如何使用find命令打印文件大小和文件名?

Unix 如何使用find命令打印文件大小和文件名?,unix,command-line,find,solaris,Unix,Command Line,Find,Solaris,如果我按如下方式发出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 你可以试试这

如果我按如下方式发出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
你可以试试这个:

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中使用-ls选项:

find . -name \*.ear -ls
这将以正常的“ls-l”格式提供每个条目。或者,要获得您想要的特定输出,请执行以下操作:

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

这将为您提供文件名和大小(KB)。

您需要使用-exec或-printf。Printf的工作原理如下:

find . -name *.ear -printf "%p %k KB\n"
-exec功能更强大,允许您执行任意命令,因此您可以使用“ls”或“wc”版本打印文件名和其他信息。”man find'将向您显示printf的可用参数,printf可以做的不仅仅是文件大小

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

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

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

使用gnu find,我想这就是您想要的。它查找所有真实文件而不是目录(-type f),并为每个文件打印文件名(%p)、制表符(\t)、大小(以KB为单位(%k)、后缀“KB”,然后是换行符(\n)

如果printf命令的格式不符合您的要求,您可以使用exec,然后是要在每个文件上执行的命令。使用{}作为文件名,并用分号(;)终止命令。在大多数shell中,这三个字符都应该用反斜杠转义

这里有一个简单的解决方案,可以使用“ls-lh”查找并打印出来,它将以人类可读的形式显示大小(k表示千字节,M表示兆字节):

作为另一种选择,“wc-c”将打印文件中的字符数(字节):

find . -type f -exec wc -c \{\} \;

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
$find-名称“test*”-exec du-sh{}\; 4.0K./test1 0./test2 0./test3 0./test4 $

我在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
    

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

    find . -name "*.ear" -exec du -a {} \;
    
    在Mac上工作

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

    这将只提供文件大小,而不是所有不必要的内容。

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

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


    请尝试以下命令:

    GNU
    stat

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

    find . -type f -name *.ear -exec stat -c "%n %s" {} ';'
    
    find . -type f -name *.ear -exec stat -f "%N %z" {} ';'
    
    但是
    stat
    不是标准,因此
    du
    wc
    可能是更好的方法:

    find . -type f -name *.ear -exec sh -c 'echo "{} $(wc -c < {})"' ';'
    
    find-键入f-name*.ear-exec sh-c'echo“{}$(wc-c<{})”“”;'
    
    如果您需要获取总大小,这里有一个脚本建议

    #!/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"
    

    您可以尝试循环:

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

    看起来您的示例更精确,但我似乎无法让该示例在Solaris 10上运行。我担心Solaris find根本不支持-printf:如果您觉得麻烦的话,可以安装GNU find,否则您需要使用exec或|正如其他人建议的那样。+1这看起来更干净。要格式化输出,我希望添加
    命令<代码>查找-name*.ear-printf“%p%k KB\n”| column-t这个答案比公认的答案正确得多
    -printf
    选项在OS X中也不起作用。请参阅。此版本将对每个文件执行“ls”进程。如果你有很多文件(比如说一千多个),你最好通过以下两种方式来优化:
    find-名称'*.ear'-exec ls-lh{}+\(GNU扩展名)或
    查找-名称'*.ear'-print0 | xargs-0 ls-lh
    。此外,如果您只对文件感兴趣,您可能希望添加
    -type f
    (或者如果您希望目录本身不包含其内容,则将
    -d
    添加到ls)。您的答案不排除目录,因此您也将在目录上运行ls,这显然不是正确的做法。这是一种非常低效的做事方式——不幸的是,ash108的评论也不理想。最好使用-printf选项来查找.dmazzoni的答案更有效,因为它避免了在每个文件上使用fork+exec(在我的机器上快100倍)。我必须将%k更改为%s@FaheemMitha:您可以添加像
    -type f
    这样的选项来只计算常规文件。@FaheemMitha简单的解决方案是
    查找-文件名“*.ear”-键入f
    <代码>-键入d
    适用于目录。
    wc
    更适用于此,如果您需要以字节为单位的大小。这只提供文件大小,不提供磁盘使用率,而不是文件大小。它们是相同的。此返回的值对于任何支持压缩的文件系统都是错误的。+1除了在示例中省略了
    -name'*.ear'
    ,这应该是#1的答案。它准确地回答了这个问题,解释了语法的含义,并给出了多种选择。这应该是可以接受的答案,因为它不会对每一行运行新命令,因此它比Shyam当前接受的命令快得多。确实,这应该是正确的answe
    find . -type f -name *.ear -exec stat -c "%n %s" {} ';'
    
    find . -type f -name *.ear -exec stat -f "%N %z" {} ';'
    
    find . -type f -name *.ear -exec sh -c 'echo "{} $(wc -c < {})"' ';'
    
    #!/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"
    
    for i in `find . -iname "*.ear"`; do ls -lh $i; done