BI应用中,对接口规范性约束很重要,接口文件提供需要配套提供该文件的校验文件,校验文件格式如下:

需要对文件进行如下方式校验:

采用shell方式实现如下:

#! /bin/bash
#**********************************************
#*** 程序功能: 文件级校验
#*** 输入参数: <数据文件路径> <校验报告路径> <接口编码> <数据日期>
#*** 编 写 人:
#*** 编写日期:
#*** 修 改 人:
#*** 修改日期:
#********************************************** #导入常用变量
. ./public.sh #校验成功
readonly VERFIRY_SUCC='' #接口文件名与规则不符,该规则目前没有做
readonly FILE_NAME_ERR='' #接口数据文件不存在
readonly FIEL_NOT_EXISTS='' #接口数据文件无法打开
readonly FILE_OPEN_ERR='' #文件大小不符
readonly FILE_SIZE_ERR='' #文件记录数不符
readonly FILE_NUM_ERR='' #文件数据日期不符
readonly FILE_DATE_ERR='' #数据文件数据日期非法
readonly FILE_DATE_UNLAW='' #数据文件记录非法结束符(非回车换行),--05新增
readonly FILE_RS='' #数据文件大小超过2,,,000Bytes
readonly FILE_SIZE_UNLAW='' #校验文件记录格式错误
readonly VERF_LINE_ERR='' #校验文件记录非法结束符(非回车换行),--05新增
readonly VERF_RS='' #校验文件无法打开
readonly VERF_OPEN_ERR='' #文件分隔符
readonly FILE_SEP='€' #返回值
verf_return=${VERFIRY_SUCC} #***************************************************
#** 函 数 名: if_verify()
#** 函数功能: 判断校验文件的格式是否正确
#** 输入参数: 校验文件名
#***************************************************
if_verify()
{
#字段数量
field_count= #校验文件报告文件名
file_verf_name=$(echo "${file_verf}"|awk -F. '{print $1}')_000.verf #判断校验文件是否能打开
if [ ! -r ${inter_path}/${file_verf} ]
then
printf ${file_verf}${FILE_SEP}`date +%Y%m%d%H%M%S`${FILE_SEP}${VERF_OPEN_ERR} >${report_path}/f_${file_verf_name}
#返回值
return
else
#判断字段数量是否符合要求
awk -F${FILE_SEP} '{print NF}' ${inter_path}/${file_verf} |while read field_count
do
#判断字段个数是否是5个,如果不是返回错误
if [ ${field_count} -ne ]
then
printf ${file_verf}${FILE_SEP}`date +%Y%m%d%H%M%S`${FILE_SEP}${VERF_LINE_ERR} >${report_path}/f_${file_verf_name}
#返回值
return
fi
done
fi #无违规项,返回0
#return
} #***************************************************
#** 函 数 名: date_unlawless()
#** 函数功能: 判断时间是否合法
#** 输入参数: 输入待检查字符
#***************************************************
date_unlawless()
{
#检查字符
date_string=$ #字符长度
str_length=${#date_string} #判断日期长度是否为6、8或10
if [ ${str_length} -eq -o ${str_length} -eq -o ${str_length} -eq ]
then
#年
year=$(echo ${date_string}|cut -c1- )
#月
month=$(echo ${date_string}|cut -c5- )
else
#echo
return
fi cal ${month} ${year}
#判断年月是否合法
if [ $? -eq ]
then
#echo
return
else #日期格式为YYYYMMDD
if [ ${str_length} -ge ]
then
#日
day=$(echo ${date_string}|cut -c7- ) #小时
hour=$(echo ${date_string}|cut -c9- ) #当月最后一天的日期
last_day=$(cal ${month} ${year}|sed '/^$/d'|tail -|awk '{print $NF}' ) #判断文件中的天是否大于实际天数
if [ ${day} -gt ${last_day} ]
then
#echo
return
fi #判断文件中的小时是否大于24 注:只有日期包含小时的时候,才校验小时
if [ ${str_length} -eq ]
then
if [ ${hour} -gt ]; then
return
fi
fi
fi
fi # echo
} #***************************************************
#** 函 数 名: file_verify()
#** 函数功能: 数据文件校验内容,根据校验文件中的记录
#** 判断数据文件是否符合规范要求
#** 输入参数: 校验文件
#***************************************************
file_verify()
{
#校验文件名
file_name=$ #函数返回值
_ret_fun= #读取校验文件中的记录
while read LINE
do
verf_return=${VERFIRY_SUCC} #得到文件名
data_file=$(echo ${LINE}|awk -F${FILE_SEP} '{print $1}') #得到校验文件名
verf_file=$(echo "${data_file}"|sed 's/dat/verf/') #得到文件大小
data_file_size=$(echo ${LINE}|awk -F${FILE_SEP} '{print $2}') #得到文件中包含的记录数
data_num=$(echo ${LINE}|awk -F${FILE_SEP} '{print $3}') #得到数据日期
data_date=$(echo ${LINE}|awk -F${FILE_SEP} '{print $4}') #得到文件生成的时间
file_time=$(echo ${LINE}|awk -F${FILE_SEP} '{print $5}') #记录格式头
head_str=${data_file}${FILE_SEP}`date +%Y%m%d%H%M%S`${FILE_SEP} #判断接口文件名与规则是否相符
echo "${data_file}" | grep "${DATAFILE_PATTERN}" >/dev/null
if [ $? -ne ]
then
verf_return=${FILE_NAME_ERR}
printf "${head_str}${verf_return}\r\n" >${report_path}/f_${verf_file} #函数返回值
let "_ret_fun+=1" continue
fi #判断数据文件是否存在
if [ ! -f ${inter_path}/${data_file} ]
then
verf_return=${FIEL_NOT_EXISTS}
printf "${head_str}${verf_return}\r\n" >${report_path}/f_${verf_file} #函数返回值
let "_ret_fun+=1" continue
fi #判断数据文件是否可以打开
if [ ! -r ${inter_path}/${data_file} ]
then
verf_return=${FILE_OPEN_ERR}
printf "${head_str}${verf_return}\r\n" >${report_path}/f_${verf_file} #函数返回值
let "_ret_fun+=1" continue
fi #实际文件大小不符
file_fact_size=$(ls -Ll ${inter_path}/${data_file}|awk '{print $5}') #判断文件大小是否符合
if [ ${file_fact_size} -ne ${data_file_size} ]
then
verf_return=${FILE_SIZE_ERR}
printf "${head_str}${verf_return}\r\n" >${report_path}/f_${verf_file} #函数返回值
let "_ret_fun+=1" continue
fi #实际文件记录数
file_fact_num=$(awk 'END{print NR}' ${inter_path}/${data_file}) #判断文件记录数不符
if [ ${file_fact_num} -ne ${data_num} ]
then
verf_return=${FILE_NUM_ERR}
printf "${head_str}${verf_return}\r\n" >${report_path}/f_${verf_file} #函数返回值
let "_ret_fun+=1" continue
fi #文件数据日期不符
if [ ${data_date} -ne ${file_data_date} ]
then
verf_return=${FILE_DATE_ERR}
printf "${head_str}${verf_return}\r\n" >${report_path}/f_${verf_file} #函数返回值
let "_ret_fun+=1" continue
fi #数据文件数据日期非法
date_unlawless ${data_date} #判断日期是否合法
if [ $? -ne ]
then
verf_return=${FILE_DATE_UNLAW}
printf "${head_str}${verf_return}\r\n" >${report_path}/f_${verf_file} #函数返回值
let "_ret_fun+=1" continue
fi #数据文件大小超过2,,,000Bytes
if [ ${file_fact_size} -gt ]
then
verf_return=${FILE_SIZE_UNLAW}
printf "${head_str}${verf_return}\r\n" >${report_path}/f_${verf_file} #函数返回值
let "_ret_fun+=1" continue
fi #没有检测到错误返回成功信息
printf "${head_str}${verf_return}\r\n" > ${report_path}/f_${verf_file}
#echo "${head_str}${verf_return}" > ${report_path}/f_${verf_file} done < ${file_name} #返回值
return ${_ret_fun}
} #***************************************************
#** 函 数 名: main()
#** 函数功能: 主程序
#** 输入参数: 数据文件路径 校验报告路径 接口编码 数据日期
#*************************************************** #判断参数是否合法
if [ $# -ne ]
then
echo "parameter error!"
echo "Usage: ./file_verrify.sh <数据文件路径> <校验报告路径> <接口编码> <数据日期>"
exit
fi #初始化变量,文件路径
inter_path=$ #校验报告文件路径
report_path=$ #接口编码
inter_code=$ #数据日期
file_data_date=$ #数据文件的正则表达式配置
DATAFILE_PATTERN="[a,i]_.*${file_data_date}_.*${inter_code}_[0-9]\{2\}_[0-9]\{3\}.dat" #校验报告路径
if [ ! -d ${report_path} ]
then
#建目录
mkdir -p ${report_path}
fi #提取校验文件
if [ -z `ls ${inter_path}/*${file_data_date}_*${inter_code}_??.verf 2>/dev/null` ]; then
echo "verify file is not exist! "
exit 1
else
file_verf=$(ls ${inter_path}/*${file_data_date}_*${inter_code}_??.verf|awk -F/ '{print $NF}')
fi #进行校验文件合法性判断
if_verify #如果校验文件错误,不进行数据文件的校验
if [ $? -ne 0 ]; then
echo "verify file error! "
exit 1
fi #进行数据文件的校验
file_verify ${inter_path}/${file_verf}
if [ $? -ne 0 ]; then
echo "data file error! "
exit 1
fi

序号

信息内容

数据类型及长度

说明

1

接口数据文件名称

CHAR(50)

2

文件的大小(字节数)

NUMBER(20)

文件的物理存储大小

3

文件中包含的记录数

NUMBER(20)

4

数据日期

CHAR(10)

如果抽取周期为小时,则格式则格式为:YYYYMMDDHH(HH采用24小时制,取值00-23);如果抽取周期为日,则格式则格式为:YYYYMMDD;如果抽取周期为月,则格式为:YYYYMM;

5

文件的生成时间

CHAR(14)

日期格式:YYYYMMDDHH24MISS

6

0x0D0A

行间分隔符-回车换行符

序号

校验结果代码

校验结果描述

1

00

校验成功

2

01

接口文件名与规则不符

3

02

接口数据文件不存在

4

03

接口数据文件无法打开

5

05

文件大小不符

6

06

文件记录数不符

7

07

文件数据日期不符

8

08

数据文件数据日期非法

9

10

数据文件接口单元编码非法

10

11

数据文件记录非法结束符(非回车换行)

11

12

数据文件大小超过2,000,000,000Bytes

12

13

接口数据文件重复上传

13

14

数据文件数据日期与期待日期不符

14

16

校验文件记录格式错误

15

92

校验文件数据日期与期待日期不符

16

93

校验文件重复上传

17

94

校验文件接口单元编码非法

18

95

校验文件记录非法结束符(非回车换行)

19

97

校验文件数据日期非法

20

98

校验文件记录长度不符

21

99

校验文件无法打开

ETL应用:使用shell实现文件级校验的方法的更多相关文章

  1. 【Shell脚本】运行shell脚本文件的几种方法与区别

    Shell脚本不同的运行方式会对当前Shell设置或者运行结果有所不同. 假设现在有一个脚本名为display_shell_script_args.sh,其内容如下: #!/home/pyf/bin/ ...

  2. ETL应用:使用Pro*C写入文件信息入库的方法

    ETL处理过程中,经常需要进行文件校验,如文件级校验.记录级校验,需要保存文件的基本信息,文件名.文件大小.数据日期等,使用Pro*C的一种方法如下: #include <stdio.h> ...

  3. 让你提前知道软件开发(22):shell脚本文件操作

    文章1部分 再了解C语言 shell脚本中的文件操作 [文章摘要] 编写shell脚本时,经常会涉及到对文件的操作,比方从文件里读取一行数据.向文件追加一行数据等. 完毕文件读写操作的方法有非常多,了 ...

  4. Shell命令-文件及目录操作之file、md5sum

    文件及目录操作 - file.md5sum 1. file:显示文件的类型 file命令的功能说明 用于辨识文件类型.通过 file 指令,我们得以辨识该文件的类型. file命令的语法格式 file ...

  5. 缓存篇(Cache)~第三回 HttpModule实现网页的文件级缓存

    返回目录 再写完缓存篇第一回之后,得到了很多朋友的好评和来信,所以,决定加快步伐,尽快把剩下的文章写完,本篇是第三回,主要介绍使用HttpModule实现的文件级缓存,在看本文之前,大家需要限度Htt ...

  6. shell判断文件是否存在

    转自:http://www.cnblogs.com/sunyubo/archive/2011/10/17/2282047.html 1. shell判断文件,目录是否存在或者具有权限 2. #!/bi ...

  7. Eclipse打开xml文件报校验错误解决办法

    XML文件在Eclipse中报校验错误: The content of element type "web-app" must match "(icon?,display ...

  8. Linux shell判断文件和文件夹是否存在

    shell判断文件,目录是否存在或者具有权限 #!/bin/sh myPath="/var/log/httpd/" myFile="/var /log/httpd/acc ...

  9. [IT新应用]存储入门-文件级存储及块级别存储的选择

    http://www.techrepublic.com/blog/the-enterprise-cloud/block-level-storage-vs-file-level-storage-a-co ...

随机推荐

  1. goldengate原理与简单配置

    goldengate的原理:http://www.ipresst.com/works/52bc44c42954a7d73b0003f2 简单单向配置: 在oracle官网下载下载 GoldenGate ...

  2. CSS基础4——使用CSS格式化元素内容的文本

    CSS的文本属性用于控制文本的段落格式,如设置首行缩进.段落对齐方式.字间距.行间距等. 1.设置文本首行缩进:text-indent 可选属性值包含: 长度 / 百分比 2.设置文本对齐方式:tex ...

  3. poj 3469(网络流模版)

    题目链接:http://poj.org/problem?id=3469 思路:终于把网络流的模版测试好了,在Dinic和Sap之间还是选择了Sap,事实证明Sap确实比Dinic效率高,在此贴出自己的 ...

  4. yii2 刷新缓存(刷新模型缓存)

    Yii2开启表结构缓存,因为当运用模型(model)时,AR的一些公共属性都会从DB中获取,这样会导致服务器负担一些额外的资源开销,实际上对于成品来说,服务器这些开始销是多余的,故应该阻止这种默认行为 ...

  5. Harmonic Value Description(构造题)

    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission ...

  6. EasyGBS国标流媒体服务器GB28181国标方案安装使用文档

    EasyGBS - GB28181 国标方案安装使用文档 下载 安装包下载,正式使用需商业授权, 功能一致 在线演示 在线API 架构图 EasySIPCMS SIP 中心信令服务, 单节点, 自带一 ...

  7. SQL Server函数​

    阅读目录 SQL Server函数---Union与Union All的区别 回到顶部 SQL Server函数---Union与Union All的区别 如果我们需要将两个select语句的结果作为 ...

  8. redis集群报错,(error) MOVED 15495 127.0.0.1:7003

        节点会对命令请求进行分析和key的slot计算,并且会查找这个命令所要处理的键所在的槽.如果要查找的哈希槽正好就由接收到命令的节点负责处理, 那么节点就直接执行这个命令. 另一方面, 如果所查 ...

  9. py 与 pyc 文件

    本文要说明的问题 pyc 文件是什么 pyc 文件的作用 py 与 pyc 文件冲突 pyc 文件是什么 当 py 文件加载后,py 文件被二进制编码成 pyc 文件.py 文件的修改时间被记录到 p ...

  10. django database relations

    注意Django的生成的默认api from django.db import models class Place(models.Model): ''' pass class Restaurant( ...