【问题标题】:Calculate size of files in shell计算shell中文件的大小
【发布时间】:2010-10-10 14:04:06
【问题描述】:

我正在尝试仅使用 shell 计算与文件名模式匹配的所有文件(在目录树中)的总大小(以字节为单位)。这是我目前所拥有的:

find -name *.undo -exec stat -c%s {} \; | awk '{total += $1} END {打印总计}'

有没有更简单的方法来做到这一点?我觉得应该有一个简单的 du 或 find 开关可以为我执行此操作,但我找不到。

为了清楚,我想在目录树下的任何地方对匹配模式的文件进行总计,这意味着

du -bs *.undo

不起作用,因为它只匹配当前目录中的文件。

【问题讨论】:

  • 无论如何,du(或ls)在几千个文件上不起作用(“参数列表太长”错误)。

标签: linux shell


【解决方案1】:

试试:

find . -name "*.undo" -ls | awk '{total += $7} END {print total}'

在我的系统上,文件的大小是find -ls 输出中的第七个字段。如果您的find … -ls 输出不同,请调整。

在这个版本中,使用现有的目录信息(文件大小)和 find 的内置 ls 功能应该是高效的,避免进程创建或文件 i/o。

【讨论】:

  • 应该可以,但是查找的 -ls 选项和 awk 对这项任务来说太过分了。
  • 如果有匹配“*.undo” glob 的目录,我会在 find 命令中添加“-type f”以防止总数不正确。
  • 请注意,如果您需要匹配多个模式,则必须使用转义括号来匹配整个表达式,否则-ls 将仅适用于最后一个模式。例如,如果您想匹配所有 jpeg 和 png 文件(信任文件名),您可以使用 find . \( -iname "*.jpg" -o -iname "*.jpeg" -o -iname "*.png" \) -ls | awk '{total += $7} END {print total}'-iname 用于不区分大小写的搜索;另外,请注意表达式和转义括号之间的空格)。跨度>
  • 这是真的在 Linux 中实现dir *.undo /s 的最简单方法吗?
【解决方案2】:

使用 zsh,您可以使用扩展通配符来执行以下操作:

du -c **/*.undo

【讨论】:

    【解决方案3】:
    find -name *.undo -print0 | du -hc --files0-from=-
    

    【讨论】:

    • 这会列出所有文件。有没有办法只显示总数?无论如何,我认为这是一个“正确答案”候选者。
    • 我喜欢这个,因为它显示了“人类可读”的大小。 @Tyler Collier 仅显示总使用尾:find -type f -name '*.undo' -print0 | du -hc --files0-from=- | tail -n 1
    • 这是我见过的在 linux 上执行此操作的最佳答案......它的执行速度也比我见过的任何其他答案快 1,000 倍,因为文件上的 du 执行速度如此之快,加上它以人类可读的术语提供输出
    • -files0-from 如果文件太多,则无法正常工作,我收到有关文件名过长的错误
    【解决方案4】:
    du -c *pattern*
    

    这将在输出的最后一行打印总数。

    【讨论】:

    • 并使用 tail 修剪除最后一行之外的所有内容。 +1。 =]
    • 这只会在当前目录中找到与模式匹配的文件,不是吗?
    • 您可以使用*/*.undo...之类的模式,尽管这只会找到带有撤消扩展名且深一个文件夹的文件...也不会在当前目录中找到任何文件。
    • 迄今为止最简单的解决方案!
    • du -ch *pattern* 获取人类可读格式的结果(例如,99K 42M 67.8G)
    【解决方案5】:

    我也一直在研究这个问题(仅仅一年后......) - 才发现这个页面。

    我发现的东西(对我来说)如下:

    find /mnt/iso -name *.avi -printf "%s\n" | paste -sd+ - | bc
    

    这将返回 /mnt/iso 下所有子文件夹中所有 .avi 文件的总大小

    我必须感谢 radoulov 的粘贴命令 - 请参阅此页面: Shell command to sum integers, one per line?

    只是添加 - 以防文件夹与搜索词匹配 - 在查找命令中也使用 -type f 是个好主意。

    【讨论】:

      【解决方案6】:
      find -name '*.undo' -exec wc -c {} + | tail -n 1
      

      应该给出文件中的实际总字节数,如果您没有太多文件(“太多”将是一个非常大的数字,可能有数千个)。或者,如果您只想单独获取号码,

      find -name '*.undo' -exec wc -c {} + | tail -n 1 | cut -d' ' -f 1
      

      【讨论】:

      • 您应该引用 '.undo'、".undo"、*.undo 或类似名称;否则,如果当前目录下存在 .undo 文件,将会得到错误的结果。
      【解决方案7】:

      Python 是大多数 linux 发行版的一部分。

      import os
      import fnmatch
      size= 0
      for path, dirs, files in os.walk( '.' ):
          for f in files:
              if fnmatch.fnmatch(f,'*.py'):
                  fileSize= os.path.getsize( os.path.join(path,f) ) 
                  print f, fileSize
                  size += fileSize
      print size
      

      冗长,但非常清晰且高度可扩展。

      【讨论】:

        【解决方案8】:
        find -name '*.undo' -print0 | du -hc --files0-from=- | tail -n 1
        

        汇总gerdemb 和 strager 的贡献。使用du -cb 应该显示字节。

        【讨论】:

          【解决方案9】:

          我使用这样的 du 命令只获取数字:

          du file_list | awk '{s+=$1} END {print s}'
          

          【讨论】:

            【解决方案10】:

            这个简单的怎么样。

            find ./ -name *.undo | xargs wc
            

            【讨论】:

              【解决方案11】:

              或者,您可以这样做:

              dir=$1
              
              for file in $dir/* ; do
              
               length_file=`stat -c %s $file`
               echo "File $file has length $length_file"
               length_total=`expr $length_total + $length_file`
              
              done
              
              echo "Total length: $length_total ."
              

              其中 stat 显示文件或文件系统状态。参数 -c 表示使用指定格式而不是默认格式,格式序列 $s 允许显示字节的总大小。

              expr 
              

              只计算一个表达式。

              【讨论】:

                【解决方案12】:

                Perl 单行:

                find . -name "*.undo" -ls | perl -lane '$t += $F[6]; END{print $t}'
                

                @F 自动拆分数组从索引 $F[0] 开始,而 awk 字段从 $1 开始,因此使用 $F[6] 代替 awk 的 $7

                【讨论】:

                  【解决方案13】:

                  du -c | awk '/./{line=$0} END{print $1}'

                  【讨论】:

                    【解决方案14】:

                    我认为带有 xargs 的版本可以改进(简化) ls -1 *.undo | xargs 厕所

                    【讨论】:

                      【解决方案15】:

                      检查du(磁盘使用)命令。

                      【讨论】:

                        猜你喜欢
                        • 1970-01-01
                        • 1970-01-01
                        • 2011-08-17
                        • 1970-01-01
                        • 2010-12-22
                        • 2012-02-06
                        • 1970-01-01
                        • 1970-01-01
                        • 1970-01-01
                        相关资源
                        最近更新 更多