【发布时间】:2021-03-28 10:12:26
【问题描述】:
其中一个 sql 逻辑正在移动到后端,我需要使用 shell 脚本生成报告。 为了便于理解,我将其简化如下。
我的输入文件 - sales.txt(id、价格、月份)
101,50,2019-10
101,80,2020-08
101,80,2020-10
201,100,2020-09
201,350,2020-10
每个 id 的输出应为 6 个月的窗口,例如 t1=2020-07 和 t2=2020-12
101,50,2020-07
101,80,2020-08
101,80,2020-09
101,80,2020-10
101,80,2020-11
101,80,2020-12
201,100,2020-09
201,350,2020-10
201,350,2020-11
201,350,2020-12
对于 id 101,虽然没有 2020-07 的条目,但它应该取自销售文件中可用的上个月的值。
所以 2019-10 的 price=50 用于 2020-07。
对于201,第一个条目本身是从 2020-09 开始的,因此 2020-08 和 2020-07 不适用。
只要有差距,就应该传播上个月的值。
我正在尝试使用 awk 来解决这个问题,我正在创建一个可重复使用的脚本 util.awk,如下所示 要生成缺失值,请将其传递给 sort 命令,然后再次使用 util.awk 进行最终输出。
util.awk
function get_month(a,b,t1) { return strftime("%Y%m",mktime(a " " b t1)) }
BEGIN { ss=" 0 0 0 "; ts1=" 1 " ss; ts2=" 35 " ss ; OFS="," ; x=1 }
{
tsc=get_month($3,$4,ts1);
if ( NR>1 && $1==idp )
{
if( tsc == tsp) { print $1,$2,get_month($3,$4,ts1); x=0 }
else { for(i=tsp; i < tsc; i=get_month(j1,j2,i) )
{
j1=substr(i,1,4); j2=substr(i,5,2);
print $1,tpr,i;
}
}
}
tsp=get_month($3,$4,ts2);
idp=$1;
tpr=$2;
if(x!=0) print $1,$2,tsc
x=1;
}
但它无限运行awk -F"[,-]" -f utils.awk sales.txt
虽然我在 awk 中尝试过,但我也欢迎其他适用于 bash 环境的答案。
【问题讨论】:
-
sql logic is moving to backend是什么意思?当我听到/看到backend时,我想到了数据库服务器,但是与(sql)数据库相关的问题中没有任何内容......??您的输入文件中有多少行 (sales.txt)? -
当我运行它生成的代码时:
101,50,201910、101,50,201911、101,50,196912,最后一个 (101,50,196912) 一遍又一遍地重复(无限循环?);196912看起来像纪元时间减去 1 秒,这很可能是由于mktime()(???) 的缺失/空/空/无效参数而发生的;第一次通过for循环,j1,j2是未定义的,所以不确定这对for增量组件有什么作用;for循环的增量为i=get_month(j1,j2,i),其中i是一个 6 位数字,如YYYYMM,这似乎不是函数的有效参数 (???) ...跨度> -
...我建议在战略位置添加一些
print命令以显示您的变量...从中您应该能够了解逻辑在哪里导轨;为了防止主调用滚动到屏幕之外,请考虑:awk -F"[,-]" -f utils.awk sales.txt | head -100(调整head参数以显示足够的信息以用于多个循环)