计算数千个文件的组合文件大小
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
我们有一个软件包可以通过为这批文件分配作业编号来执行任务。批处理中可以包含任意数量的文件。然后将文件存储在类似于此的目录结构中:
/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