Linux 合计测量某些文件类型的磁盘空间

Linux 合计测量某些文件类型的磁盘空间,linux,bash,unix,diskspace,Linux,Bash,Unix,Diskspace,我有几个文件夹中的一些文件: /home/d/folder1/a.txt /home/d/folder1/b.txt /home/d/folder1/c.mov /home/d/folder2/a.txt /home/d/folder2/d.mov /home/d/folder2/folder3/f.txt 如何测量/home/d/中所有.txt文件占用的磁盘空间总量 我知道du会给我给定文件夹的总空间,而ls-l会给我单个文件的总空间,但是,如果我想把所有的txt文件加起来,只看一下/hom

我有几个文件夹中的一些文件:

/home/d/folder1/a.txt
/home/d/folder1/b.txt
/home/d/folder1/c.mov
/home/d/folder2/a.txt
/home/d/folder2/d.mov
/home/d/folder2/folder3/f.txt
如何测量/home/d/中所有.txt文件占用的磁盘空间总量


我知道du会给我给定文件夹的总空间,而ls-l会给我单个文件的总空间,但是,如果我想把所有的txt文件加起来,只看一下/home/d/中所有.txt文件所占的空间,包括folder1和folder2及其子文件夹folder3,该怎么办?

查找folder1 folder2-iname'*.txt'-print0|du--c-s|tail-1的文件0这样就可以了它:

total=0
对于*.txt格式的文件
做
空格=$(ls-l“$file”| awk'{print$5}')
设总+=空间
完成
echo$总计
以下是一种方法(在Linux中,使用GNU coreutils和Bash语法),避免:

请注意,对于包含换行符的文件名,这些命令无法正常工作(但带有空格的命令可以正常工作)。

macOS

  • 使用工具
    du
    和参数
    -I
    排除所有其他文件
Linux

GNU发现

find /home/d -type f -name "*.txt" -printf "%s\n" | awk '{s+=$0}END{print "total: "s" bytes"}'

在ennuikiller的基础上,这将处理名称中的空格。我需要这样做并得到一个小报告:

查找-类型f-名称“*.wav”| grep export |/计算空间

#!/bin/bash
# calc_space
echo SPACE USED IN MEGABYTES
echo
total=0
while read FILE
do
    du -m "$FILE"
    space=$(du -m "$FILE"| awk '{print $1}')
    let total+=space
done
echo $total

这将按扩展名以字节为单位报告磁盘空间使用情况:

find . -type f -printf "%f %s\n" |
  awk '{
      PARTSCOUNT=split( $1, FILEPARTS, "." );
      EXTENSION=PARTSCOUNT == 1 ? "NULL" : FILEPARTS[PARTSCOUNT];
      FILETYPE_MAP[EXTENSION]+=$2
    }
   END {
     for( FILETYPE in FILETYPE_MAP ) {
       print FILETYPE_MAP[FILETYPE], FILETYPE;
      }
   }' | sort -n
    find . -type f -print0 | xargs -0 stat -f "%N %i" |
  awk '{
      PARTSCOUNT=split( $1, FILEPARTS, "." );
      EXTENSION=PARTSCOUNT == 1 ? "NULL" : FILEPARTS[PARTSCOUNT];
      FILETYPE_MAP[EXTENSION]+=$2
    }
   END {
     for( FILETYPE in FILETYPE_MAP ) {
       print FILETYPE_MAP[FILETYPE], FILETYPE;
      }
   }' | sort -n
输出:

3250 png
30334451 mov
57725092729 m4a
69460813270 3gp
79456825676 mp3
131208301755 mp4
简单:

du-ch*.txt
如果您只想显示占用的总空间,则:

du-ch*.txt | tail-1

针对在bash上使用GNU工具的用户的一行程序:

for i in $(find . -type f | perl -ne 'print $1 if m/\.([^.\/]+)$/' | sort -u); do echo "$i"": ""$(du -hac **/*."$i" | tail -n1 | awk '{print $1;}')"; done | sort -h -k 2 -r
必须启用extglob:

shopt -s extglob
如果要使点文件工作,必须运行

shopt -s dotglob
样本输出:

d: 3.0G
swp: 1.3G
mp4: 626M
txt: 263M
pdf: 238M
ogv: 115M
i: 76M
pkl: 65M
pptx: 56M
mat: 50M
png: 29M
eps: 25M

etc

我喜欢将find与xargs结合使用:

find . -name "*.txt" -print0 |xargs -0 du -ch
如果您只想看到总计,请添加尾部

find . -name "*.txt" -print0 |xargs -0 du -ch | tail -n1

我的解决方案是获得给定路径和子目录中所有文本文件的总大小(使用perl oneliner)


对于希望在命令行使用macOS执行此操作的任何人,都需要基于-print0参数而不是printf的变体。上面的一些答案解决了这一问题,但这将通过扩展全面解决这一问题:

find . -type f -printf "%f %s\n" |
  awk '{
      PARTSCOUNT=split( $1, FILEPARTS, "." );
      EXTENSION=PARTSCOUNT == 1 ? "NULL" : FILEPARTS[PARTSCOUNT];
      FILETYPE_MAP[EXTENSION]+=$2
    }
   END {
     for( FILETYPE in FILETYPE_MAP ) {
       print FILETYPE_MAP[FILETYPE], FILETYPE;
      }
   }' | sort -n
    find . -type f -print0 | xargs -0 stat -f "%N %i" |
  awk '{
      PARTSCOUNT=split( $1, FILEPARTS, "." );
      EXTENSION=PARTSCOUNT == 1 ? "NULL" : FILEPARTS[PARTSCOUNT];
      FILETYPE_MAP[EXTENSION]+=$2
    }
   END {
     for( FILETYPE in FILETYPE_MAP ) {
       print FILETYPE_MAP[FILETYPE], FILETYPE;
      }
   }' | sort -n

接受的答案存在几个潜在问题:

  • 它不会下降到子目录中(不依赖非标准的shell功能,如)
  • 一般来说,正如下面丹尼斯·威廉姆森所指出的,你应该避免
    • 也就是说,如果用户或组(第3列和第4列)中有空格,则第5列将不是文件大小
  • 如果你有一百万个这样的文件,这将产生两百万个子shell,它将是Slooow
  • 同样,您可以使用GNU特有的
    -printf
    选项来
    查找
    ,以实现更健壮的解决方案,避免所有过多的管道、子shell、Perl和怪异的
    du
    选项:

    #“%s”格式字符串表示“文件大小”
    找到-名称“*.txt”-printf“%s\n”\
    |awk'{sum+=$1}END{print sum“bytes”}'
    
    是的,是的,使用
    paste
    bc
    的解决方案也是可能的,但不是更简单

    在macOS上,您需要使用自制或MacPorts安装
    findutils
    ,然后调用
    gfind
    。(我在这个问题上看到了“linux”标签,但它也被标记为“unix”。)

    如果没有GNU
    find
    ,您仍然可以使用
    du

    find-名称“*.txt”-exec du-k{}+\
    |awk'{kbytes+=$1}END{print kbytes“kbytes”}
    
    …但您必须注意的是,由于历史原因,
    du
    的默认输出为512字节块(请参见手册的第页),并且一些版本的
    du
    (尤其是macOS)甚至没有以字节为单位打印大小的选项


    这里有许多其他的优秀解决方案(请特别注意),但大多数都有一个缺点,就是不必要地复杂,或者过于依赖GNU的特性,也许在您的环境中,这没关系

    这会在子文件夹folder1和folder2中找到文件吗?使用了一个细微的变化。删除了ls中的第一个-l。这仍然不做任何递归,它会轰炸任何有空格的东西,但这是我拥有的最接近的东西。谢谢没问题……我错过了子文件夹的要求,但通过将for命令改为find之类的命令,这很容易处理-name*.txt-exec ls{}\for循环中的ls*.txt是冗余的。只需使用shell扩展。-->对于*.txt中的文件,您的语句中有输入错误,而不是“;\”但是>找到-名称“*.txt”-exec ls{}\;du似乎没有一个--files from optoni意味着一个--files 0 from option
    du--version du(GNU coreutils)5.93在我的机器上工作。在我的Cygwin安装中:du--version du(GNU coreutils)6.10在我的linux机器上,我正在运行coreutils 4.5.3,所以它有点过时,如果你需要它在HP-UX上运行,你为什么要使用linux标签?这是迄今为止最好的解决方案,它工作得非常好。要获得人类可读的输出,如
    123GiB mp4
    ,请将输出通过管道传输到
    numfmt--field=1--To=iec-i--format“%8f”--后缀B
    。我在屏幕上找不到任何关于-i的内容。你能举个例子吗?@FelixEve请再读一遍我的答案。我想这应该是清楚的,
    -I
    只存在于运行在macOS上的
    du
    上。试试
    du-ch/home/d/***.txt | tail-1
    @FranklinClark虽然可以工作,但它依赖于
    shopt-s globstar
    ,至少在Bash.BSD(macOS)
    find
    上没有
    -printf
    选项,因此,如上所述,这是一个仅适用于GNU/Linux的选项。如果使用或安装
    findutils
    ,则可以改用
    gfind
    。如其中所述,POSIX
    du
    后来删除了
    -b
    选项,以512字节块(默认值)或1-K字节块打印用法。
    -b
    选项
    find /path -iname '*.txt' | perl -lane '$sum += -s $_; END {print $sum}'
    
        find . -type f -print0 | xargs -0 stat -f "%N %i" |
      awk '{
          PARTSCOUNT=split( $1, FILEPARTS, "." );
          EXTENSION=PARTSCOUNT == 1 ? "NULL" : FILEPARTS[PARTSCOUNT];
          FILETYPE_MAP[EXTENSION]+=$2
        }
       END {
         for( FILETYPE in FILETYPE_MAP ) {
           print FILETYPE_MAP[FILETYPE], FILETYPE;
          }
       }' | sort -n