linux - 在非常大的文件系统上获取每个文件的文件大小

标签 linux bash ubuntu filesystems centos

我必须将包含几百万个文件的 20TB 文件系统移动到 ZFS 文件系统。所以我想了解文件大小,以便做出好的 block 大小选择。

我目前的想法是 `stat --format="%s"每个文件,然后将文件分成 bin。

#!/bin/bash

A=0 # nr of files <= 2^10
B=0 # nr of files <= 2^11
C=0 # nr of files <= 2^12
D=0 # nr of files <= 2^13
E=0 # nr of files <= 2^14
F=0 # nr of files <= 2^15
G=0 # nr of files <= 2^16
H=0 # nr of files <= 2^17
I=0 # nr of files >  2^17

for f in $(find /bin -type f); do

    SIZE=$(stat --format="%s" $f)

    if [ $SIZE -le 1024 ]; then
    let $A++
    elif [ $SIZE -le 2048 ]; then
    let $B++
    elif [ $SIZE -le 4096 ]; then
    let $C++
    fi
done

echo $A
echo $B
echo $C

此脚本的问题是我无法让 find 在 for 循环中工作。

问题

如何修复我的脚本?

有没有更好的方法来获取文件系统的所有文件大小?

最佳答案

主要问题是您使用命令替换将 find 的输出提供给 for 循环。命令替换通过在括号(或反引号)内运行命令完成、收集其输出并将其替换到脚本中来工作。这不支持流式传输,这意味着 for 循环在 find 扫描完全完成之前不会运行,并且您需要大量内存来缓冲 find 的输出> 也是。

特别是因为您正在扫描值(value)数 TB 的文件,所以您需要使用支持流式处理的东西,例如 while 循环:

find /bin -type f | while read f; do
    ...
done

对于可以流式传输的内容,您的脚本至少可以工作,但请记住,这种技术会强制您为找到的每个文件调用一次外部命令 (stat)。这会为 stat 命令带来大量的进程创建、销毁和启动成本。如果你有 GNU find,例如在 find 命令中使用它的 -printf 选项输出每个文件的大小,性能会好得多。

旁白:循环体中的 let 语句看起来不对。您正在扩展 $A$B$C 变量的内容,而不是引用它们。你不应该在这里使用 $

关于linux - 在非常大的文件系统上获取每个文件的文件大小,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16132514/

相关文章:

Ubuntu 14.01.1 LTS(apt-get 更新不工作)

linux - 试图在 Shell 脚本 $(date +%j) 中找到确切的剩余天数

linux - 批量重命名文件去除 ".csv"后的后缀

bash - 生成文件 `echo -n' 不工作

linux - 用于检查文件中的路由器和接口(interface)列表上的 ATM 接口(interface)速度的 Bash 脚本

linux - 如何在 Linux 上将 PDF 转换为 DOCX

linux - 在算术表达式中,为什么递增变量会修改原始变量而其他操作不会?

linux - 对于使用 libvrt 创建的 CentOS 虚拟机,需要使用 sda(而不是 vda)进行分区

Bash 脚本 - 文件目录不存在

linux - 我可以自动化 pppoeconf 吗?