awk新风格(模块化)的业务代码
main.sh (程序入口代码)
参数DEBUG会决定logging模块的debug函数是否输出日志以方便调试,这其实是我目前形成的理念之一:
一旦我决定在这里写下一个输出语句方便调试,那么这个语句我就不会再删除了
我见过很多的研发人员(包括以前的我自己)喜欢在程序里加上一堆输出语句(alert,printf,MessageBox)打印一堆没有什么含义的语句(例如ssssssss,111111)以及变量的值,之后再删掉,删掉之后在添加,添加之后再删除。。。
其实,他们是为了确定程序状态,看看程序有没有运行到添加输出语句的位置,或者想想看看程序在那个时刻的值到底是啥,但是他们觉得这些日志语句不属于业务逻辑,只是辅助用的,而且写的极乱,所以不愿意保留,但是这东西在调试期间由非常有用(尤其是没有单步调试的开发环境),或者虽然这次开发完毕,删掉,下次需求发生变化的时候过来重新修改原来已经正确了的程序,又被迫把删除了的语句给添加上
我现在的理念就是:一旦我需要再这加日志输出了,那么我就永远不删除了,因此需要我写好每一个输出,保证每个输出容易被读懂,是有意义的,再者通过调试状态的设置,让这些语句在运行时不输出,这样就可以避免效率的降低,下面是我一个例子,因为awk没有现成的日志库,这个logging模块是我自己随手写的
#!/bin/sh cat $bookListFile | igawk -f stat.awk -v DEBUG=true -v STAT_DATE=$STAT_DATE -v USER_FILE=$auditedUserFile -v STAT_FILE=$statFile -v SCRIPT_FILE=$sqlFile
stat.awk (业务逻辑模块)
文件顶部引用的模块都是可以被复用的模块,为了体现模块化的代码就不提供源码了,只要知道每个模块都可以干啥,就可以了
- assert.awk 提供了 assert函数
- logging.awk 提供了 debug函数
- makeSql.awk提供了makeInsertSQL,makeDeleteSQL函数
我比较得意的一点是我写完makeSql.awk以后,并且想到他们该怎么样复用,我就再也不干拼SQL这样的脏活了
@include lib/assert.awk @include lib/logging.awk @include lib/makeSql.awk function makeUserList(filename,userList,__ARGVEND__) { while(getline<filename == 1) { userList[$0] } } function readStatResult(filename,statResult,__ARGVEND__,i) { i = 1 while(getline<filename == 1) { statResult[i]=$0 i++ } } BEGIN{ makeUserList(USER_FILE,USERLIST) readStatResult(STAT_FILE,RESULT) assert(length(RESULT) == 5,"assertion faild : read stat result") } { listid = $1 userid = $2 digest = $3 debug("debug 1 : userid is "userid) if(userid in nowUserList) { debug("debug 1.1 userid"userid" is find again") } else { debug("debug 1.2 userid "userid" is first find") nowUserList[userid] } } END{ debug("\ndebug 2 : in end block") newUserCounter = 0 for(i in nowUserList) { userid = i debug("debug 2.1 current userid is "userid) if(i in USERLIST) { debug("debug 2.1.1 userid "userid" is not new user!") } else { debug("debug 2.1.2 userid "userid" is new user!") newUserCounter ++ } } debug("debug 2.2 today new user count is "newUserCounter) removeInfo["stat_date"] = STAT_DATE makeDeleteSQL("stat_shuqi_book_list",removeInfo,SCRIPT_FILE) STAT["posted_list"] = RESULT[1] STAT["posted_user"] = RESULT[2] STAT["new_posted_list"] = RESULT[3] STAT["new_posted_user"] = newUserCounter STAT["posted_greet_list"] = RESULT[4] STAT["new_posted_greet_list"] = RESULT[5] STAT["stat_date"] = STAT_DATE STAT["pv"] = 0 makeInsertSQL("stat_shuqi_book_list",STAT,SCRIPT_FILE) }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· .NET周刊【3月第1期 2025-03-02】
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· [AI/GPT/综述] AI Agent的设计模式综述