做一个能反复用的校验器
目标
不再编写用完即弃的数据清理脚本,而是能够构建自动判定每周到达文件的验证器。
为什么重要
验证器真正的考验不是损坏的文件,而是正常文件。如果规则过于严格,连完好的文件也判定失败,人们就会每周想着“又是那个误报”并开始忽略它;两个月后真正的问题到来时,他们同样会忽略。此时,有验证器反而比没有更糟——它让人误以为存在保护,实际上却什么都阻止不了。
因此,验证器必须始终从两个方向测试:正常文件能否通过,损坏文件能否失败。结果还必须通过退出码表达:通过时为 0,失败时为非 0。这样才能直接接入批处理流水线。
/opt/data/validate/ 中有四个文件。其中三个以不同方式损坏,一个完好无损。所有文件的表头均为 id,customer,amount,region,date。
三项规则
- 格式:字段数恰好为 5,
customer不为空,amount为整数 - 重复:
id必须唯一(同一 id 再次出现时,该行属于违规) - 范围:
amount不小于 1 且不大于 10000000
步骤
- 创建
/root/validate目录。 - 将
bad_schema.csv中违反格式规则的行数写入/root/validate/schema_bad.txt。 - 将
bad_dupe.csv中因重复而应丢弃的行数写入/root/validate/dupe_rows.txt。 - 将
bad_range.csv中违反范围规则的行数写入/root/validate/range_bad.txt。 - 将
good.csv中的违规行数写入/root/validate/good_bad.txt。 - 将四个数值之和写入
/root/validate/total_bad.txt。 - 创建
/root/validate/validate.sh。它通过第一个参数接收 CSV 路径;如果没有任何违规,必须以退出码 0 结束,如果存在任何违规,则必须以非 0 退出码结束。 - 在
/root/validate/report.md中写明四个文件的名称、各自的违规数量以及总数。
参考
- 查找重复 id:
cut -d, -f1 파일 | tail -n +2 | sort | uniq -d - 使用
exit 0/exit 1指定退出码,运行后立即使用echo $?检查 - 评分时会分别运行
validate.sh来检查good.csv和bad_schema.csv。两者都必须判定正确才能通过。 - 常见错误 1:第 5 步得到非 0 数值。会误报的验证器很快就会被忽略。
- 常见错误 2:第 7 步只在屏幕输出结果,却不改变退出码。应优先提供机器可读取的信号。
创建工作目录
创建 /root/validate 目录。
将结果集中放在 /root/validate 下。
统计格式违规行
将 bad_schema.csv 中违反格式规则的行数写入 /root/validate/schema_bad.txt。
统计 bad_schema.csv 中违反字段数量、客户名为空或金额非整数这三项任一条件的行。
统计重复行
将 bad_dupe.csv 中因重复而应丢弃的行数写入 /root/validate/dupe_rows.txt。
统计 bad_dupe.csv 中同一 id 再次出现的行数。第一次出现的行不计入。
统计范围违规行
将 bad_range.csv 中违反范围规则的行数写入 /root/validate/range_bad.txt。
统计 bad_range.csv 中 amount 超出 1 到 10000000(含边界)范围的行。0 也属于违规。
检查正常文件
将 good.csv 中的违规行数写入 /root/validate/good_bad.txt。
good.csv 中不应存在违规。如果这里不是 0,说明验证器发生了误报。
汇总全部违规数量
将四个数值之和写入 /root/validate/total_bad.txt。
将四个文件得到的数值全部相加。
创建验证脚本
创建 /root/validate/validate.sh。它通过第一个参数接收 CSV 路径;如果没有任何违规,必须以退出码 0 结束,如果存在任何违规,则必须以非 0 退出码结束。
通过参数接收文件路径;验证通过时以退出码 0 结束,存在违规时以非 0 值结束。
编写验证报告
在 /root/validate/report.md 中写明四个文件的名称、各自的违规数量以及总数。
报告必须包含四个文件名称、各自的违规数量以及总数。