我正在尝试使用GNU Make 3.81建立一个ETL系统。我的想法是只更改和加载更改源数据后所需的内容。
我的项目目录布局如下所示:
${SCRIPTS}/ <- transform & load scripts
${DATA}/incoming/ <- storage for extracted data
${DATA}/processed/ <- transformed, soon-to-be-loaded data
我的$ {TRANSFORM_SCRIPTS} / Makefile中填充了这样的语句:
A_step_1: ${SCRIPTS}/A/do_step_1.sh ${DATA}/incoming/A_files/*
${SCRIPTS}/A/do_step_1.sh ${DATA}/incoming/A_files/* > ${DATA}/processed/A.step_1
A_step_2: ${SCRIPTS}/A/do_step_2.sh ${DATA}/processed/A.step_1
${SCRIPTS}/A/do_step_2.sh ${DATA}/processed/A.step_1 > ${DATA}/processed/A.step_2
B_step_1: ${SCRIPTS}/B/do_step_1.sh ${DATA}/incoming/B_files/*
${SCRIPTS}/B/do_step_1.sh ${DATA}/incoming/B_files/* > ${DATA}/processed/B.step_1
B_step_2: ${SCRIPTS}/B/do_step_2.sh ${DATA}/processed/B.step_1
${SCRIPTS}/B/do_step_2.sh ${DATA}/processed/B.step_1 > ${DATA}/processed/B.step_2
joined: A_step_2 B_step_2
join ${DATA}/processed/A.step_2 ${DATA}/processed/B.step_2 > ${DATA}/processed/joined
调用`make joined'成功生成我需要的“加入”文件,但每次重建每个文件,尽管依赖文件没有变化。
我尝试使用输出文件名作为目标,但GNU Make似乎不知道如何处理:
${DATA}/processed/B.step_2: ${SCRIPTS}/B/do_step_2.sh ${DATA}/processed/B.step_1
${SCRIPTS}/B/do_step_2.sh ${DATA}/processed/B.step_1 > ${DATA}/processed/B.step_2
除了删除当前工作目录中每个进程的输出之外的任何建议? Make似乎是执行此工作的合理工具,因为实际上,有数十个数据源和接近100个步骤,并且通过脚本文件自己管理依赖性变得非常困难。
答案 0 :(得分:2)
你可以做以下两件事之一:
使用以下内容修复目标及其依赖项:
JOINED=${DATA}/processed/joined
$(JOINED): ${DATA}/processed/A.step_2 ${DATA}/processed/B.step_2
或在步骤中您可以使用
结束每个步骤 touch $@
例如:
A_step_2: ${SCRIPTS}/A/do_step_2.sh ${DATA}/processed/A.step_1
${SCRIPTS}/A/do_step_2.sh ${DATA}/processed/A.step_1 > ${DATA}/processed/A.step_2 && touch $@ || $(RM) $@
包括联合步骤。
但这太丑了。