计算数千个文件的组合文件大小

Calculate combined filesize of thousands of files

我们有一个软件包可以通过为这批文件分配作业编号来执行任务。批处理中可以包含任意数量的文件。然后将文件存储在类似于此的目录结构中:

/asc/array1/.storage/10/10297/10297-Low-res.m4a
...
/asc/array1/.storage/3/3814/3814-preview.jpg

文件名是自动生成的。 .storage中的目录是文件号的千位

还有一个数据库将作业编号和文件编号与相关客户相关联。 运行 一个 SQL 查询,我可以列出作业编号、客户端和文件的完整路径。示例:

213     sample-data     /asc/array1/.storage/10/10297/10297-Low-res.m4a
...
214     client-abc      /asc/array1/.storage/3/3814/3814-preview.jpg

我的任务是计算每个客户端 使用的总存储量。因此,我编写了一个快速而肮脏的 bash 脚本来遍历每一行和 du 文件,并将其添加到关联数组中。然后我计划回应这个或生成一个 CSV 文件以摄取到 PowerBI 或其他一些工具中。这是处理这个问题的最佳方法吗?这是脚本的副本:

#!/bin/sh

declare -A clientArr

# 1 == Job Num
# 2 == Client
# 3 == Path
while read line; do
    client=$(echo "$line" | awk '{ print  }')
    path=$(echo "$line" | awk '{ print  }')

    if [ -f "$path" ]; then
        size=$(du -s "$path" | awk '{ print  }')
        clientArr[$client]=$((${clientArr[$client]}+${size}))
    fi
done < /tmp/pm_report.txt

for key in "${!clientArr[@]}"; do
    echo "$key,${clientArr[$key]}"
done

假设:

  • 你有 GNU coreutils du
  • 文件名不包含空格

这没有 shell 循环,调用 du 一次,并遍历 pm_report 文件两次。

file=/tmp/pm_report.txt

awk '{printf "%s[=10=]", }' "$file" \
| du -s --files0-from=- 2>/dev/null \
| awk '
    NR == FNR {du[] = ; next}
    {client_du[] += du[]}
    END {
      OFS = "\t"
      for (client in client_du) print client, client_du[client]
    }
  ' - "$file"

使用文件 foo:

$ cat foo
213     sample-data     foo          # this file
214     client-abc      bar          # some file I had in the dir
215     some            nonexistent  # didn't have this one

和 awk:

$ gawk '                             # using GNU awk
@load "filefuncs"                    # for this default extension
!stat(,statdata) {                 # "returns zero upon success"
    a[]+=statdata["size"]          # get the size and update array
}
END {                                # in the end
    for(i in a)                      # iterate all
        print i,a[i]                 # and output
}' foo foo                           # running twice for testing array grouping

输出:

client-abc 70
sample-data 18