• 基于awk实现的表格检查框架


    表格检查逻辑可以划分为:

    1.单行逻辑的检查

    将单行数据按列名存储成  field_list[col_name] = col_value

    2.整表逻辑检查

    将整表数据按行和列存储成 record_list[NR][col_name] = col_value

    3.跨表关联检查。

    高效的跨表检查,应该是通过多文件读取,将基准文件放在最前面,这样先从基准表构建索引表,然后再逐行检查外部约束。

    下面直接上代码,并给出示例

    框架代码  process_template.awk

    1. @include LIBNAME
    2. #process header
    3. BEGIN{
    4. check_fail = 0;
    5. }
    6. #process check
    7. {
    8. if(FNR == 1) {
    9. #读取文件名
    10. split(FILENAME, array, "/");
    11. filename=array[length(array)];
    12. #清理数组
    13. delete field_idx;
    14. delete field_list;
    15. delete record_list;
    16. #第一行读取列编号到列名的映射
    17. for(i=1; i <= NF; i++) {
    18. field_idx[i] = $i;
    19. }
    20. next;
    21. }
    22. if(FNR == 2) next;
    23. # 表格内容
    24. for(i=1; i <= NF; i++) {
    25. # 将一行数据转换为列名到列内容的映射
    26. field_list[field_idx[i]] = $i;
    27. # 记录整表数据,以行号为一级索引,列名为二级索引
    28. if(csvname == filename)
    29. record_list[FNR][field_idx[i]] = $i;
    30. }
    31. #check_record函数在LIBNAME这个文件中实现,处理单行数据
    32. rlt = check_record(field_list);
    33. if(rlt != "OK") {
    34. print "[csv check err] "filename" |line:"FNR" |err: "rlt;
    35. check_fail = 1;
    36. exit;
    37. }
    38. }
    39. #process end
    40. END{
    41. #check_table函数在LIBNAME这个文件中实现,处理整表数据
    42. rlt = check_table(record_list);
    43. if(rlt != "OK") {
    44. print "[csv check err] "csvname" |whole table|err: "rlt;
    45. check_fail = 1;
    46. }
    47. if(check_fail == 0) print "[check success] "csvname;
    48. }

    逻辑实现代码示例  example.awk

    1. #field_list是一个map,key是列名,值是字段内容
    2. #函数名check_record是固定的,请不要修改
    3. function check_record(field_list)
    4. {
    5. if(field_list["Cost Num"] > 400)
    6. {
    7. #错误返回自定的内容
    8. err = "Cost Num > 400";
    9. return err;
    10. }
    11. #OK是一个固定表示,请不要修改
    12. err = "OK";
    13. return err;
    14. }
    15. #record_list是一个二维数组,record_list[行号][列名]=字段内容
    16. #函数名check_table是固定的,请不要修改
    17. function check_table(record_list)
    18. {
    19. for(nr in record_list)
    20. {
    21. if(isarray(record_list[nr]))
    22. {
    23. total_cost += record_list[nr]["Cost Number"];
    24. }
    25. }
    26. if(total_cost > 100)
    27. {
    28. #错误返回自定的内容
    29. err = "Cost Number total > 1000";
    30. return err;
    31. }
    32. #OK是一个固定表示,请不要修改
    33. err = "OK";
    34. return err;
    35. }

    整个配置文件格式是这样的,example是csv文件的名字,每个csv对应自己的awk检查文件,文件名相同,后缀名不同

    1. #check_conf.ini
    2. example1
    3. example2

    如上图,就会有example1.awk对应检查example1.csv,example2.awk检查example2.csv

    最外部的调度脚本 check_csv.sh 是这样的:

    1. #!/bin/bash
    2. cd "$( dirname "$0" )"
    3. #单表检查逻辑
    4. while read line || [[ -n ${line} ]]
    5. do
    6. IFS=','
    7. arr=($line)
    8. IFS=' '
    9. cp ./csv_check/process_template.awk ./check_csv.awk
    10. sed -i "s/LIBNAME/\"csv_check\/${arr[0]}.awk\"/g" ./check_csv.awk
    11. gawk -F',' -v csvname="${arr[0]}.csv" -f ./check_csv.awk ${arr[0]}.csv
    12. done < ./csv_check/check_conf.ini
    13. rm -f ./check_csv.awk

    执行时,将process_template.awk拷贝出来,然后替换掉其中的include文件,这样就用具体的csv检查逻辑填充了check_record和check_table

  • 相关阅读:
    vue与react,angular的区别
    基于单片机智能手环的GPS定位信息系统设计+开题报告
    .netcore+vue新生分班系统的设计与实现
    新手必看!!附源码!!STM32通用定时器输出PWM
    flume拦截器
    【算法】递归解决各种数据结构的遍历问题
    (二十)数据结构-查找的基本概念
    TC3-Vision应用笔记
    深入体验了4大知名BI分析工具,终于找到了最适合我们公司的一款
    Webpack 中 Plugin 的作用是什么?常用 plugin 有哪些?
  • 原文地址:https://blog.csdn.net/cleanfield/article/details/127422454