目标:每天比较目录结构的大小。数据文件夹有超过 990TB 的数据,因此我不得不运行大量并行 du 才能在合理的时间内完成。有时,我们会看到大量数据快速增长,目前还没有很好的方法来查看数据添加到了哪里。
问题:我的 awk 的 $1 和 $2 没有输出任何内容,并且应该围绕它们的单引号也没有显示。
先发制人打击:我知道有更好的工具可以找到这些信息,我们正在努力实现它们。这是为了让我们在安装适当的监控软件之前解决任何快速增长的问题。此外,日志文件中两个值之间的分隔符是制表符。将其粘贴到此所见即所得编辑器中会将制表符转换为空格。
提前感谢您能给我提供的任何帮助!
斯纳夫
我正在尝试执行以下操作(伪代码)
- 在我们的数据文件夹中找到两层深的文件夹
- 在临时文件夹中创建一个镜像数据文件夹结构的目录结构
- 在临时文件夹结构中为“查找文件夹”中找到的每个文件夹创建日志文件
- 使用“查找文件夹”中文件夹的 du -s 输出填充这些日志文件
- awk 日志文件并构建 sql 插入
- 一旦 sql 插入看起来正确,我将把 awk 传输到 mysql
- 一旦数据存在于 mysql 中,就可以轻松查询每日统计数据
脚本 -
DT=`date +"%Y%m%d"`
BASE=/mnt/data/test/
find /mnt/data -maxdepth 2 -mindepth 2 -type d -exec sh -c 'mkdir -p "$(dirname '"$BASE$DT"'{}.log)";touch '"$BASE$DT"'{}.log; du -S {} > '"$BASE$DT"'{}.log; awk -F'\''\t'\'' '\''{print "INSERT INTO DATE'"$DT"'(folder_size, folder_location) VALUES('\''$1'\'', '\''$2'\'');"}'\'' '"$BASE$DT"'{}.log' \;
日志文件示例 -
0 /mnt/data/apps/bog/minio.production-config/.minio/certs/CAs
12 /mnt/data/apps/bog/minio.production-config/.minio/certs
1 /mnt/data/apps/bog/minio.production-config/.minio
1 /mnt/data/apps/bog/minio.production-config
此日志文件脚本的输出示例 -
INSERT INTO DATE20220508(folder_size, folder_location) VALUES(, );
INSERT INTO DATE20220508(folder_size, folder_location) VALUES(, );
INSERT INTO DATE20220508(folder_size, folder_location) VALUES(, );
INSERT INTO DATE20220508(folder_size, folder_location) VALUES(, );
答案1
您在这里深深地引用了地狱。
您的find
命令传递给sh -c
如下参数
mkdir -p "$(dirname /mnt/data/test/20220508/mnt/data/abc/def.log)";touch /mnt/data/test/20220508/mnt/data/abc/def.log; du -S /mnt/data/abc/def > /mnt/data/test/20220508/mnt/data/abc/def.log; awk -F'\t' '{print "INSERT INTO DATE20220508(folder_size, folder_location) VALUES('$1', '$2');"}' /mnt/data/test/20220508/mnt/data/abc/def.log
现在sh
解析它,删除一个引用级别。它将 扩展为$(dirname /mnt/data/test/20220508/mnt/data/abc/def.log)
,/mnt/data/test/20220508/mnt/data/abc
并将 中的变量$1
和$2
扩展为awk
空字符串(因为它没有收到任何位置参数),从而得到
mkdir -p /mnt/data/test/20220508/mnt/data/abc;touch /mnt/data/test/20220508/mnt/data/abc/def.log; du -S /mnt/data/abc/def > /mnt/data/test/20220508/mnt/data/abc/def.log; awk -F\t '{print "INSERT INTO DATE20220508(folder_size, folder_location) VALUES(, );"}' /mnt/data/test/20220508/mnt/data/abc/def.log
(为了清楚起见,我在程序文本参数周围重新插入了单引号awk
。)
最简单的方法是为程序创建一个文件awk
,然后awk
通过-f
选项将其传递给它。然后我还建议在该文件中进行分配,FS = "\t"
而不是使用该-F
选项。
最后,如果除了创建 SQL 语句之外,日志文件没有任何其他用途,您可以通过将输出du
直接传输到 来大大简化脚本awk
,例如:
DT=`date +"%Y%m%d"`
find /mnt/data -maxdepth 2 -mindepth 2 -type d -exec sh -c 'du -S {} | awk -v DT='$DT' -f /mnt/data/makeinserts.awk' \;
/mnt/data/makeinserts.awk
使用包含纯程序的文件awk
:
BEGIN{FS="\t"}
{print "INSERT INTO DATE"DT"(folder_size, folder_location) VALUES('"$1"', '"$2"');"}