我正在使用GNU Make,但如有必要,我愿意更改为其他内容。
我有两个目录 try {
val df=spark.table("Hive Table")
df.write.mode(SaveMode.Append).jdbc(jdbcURL, "TD Table", properties)
}catch {case ex: Exception =><print error by calling getNextException repeatedly>
和ALPHABETIC
,内容如下。
NUMERIC
和程序./ALPHABETIC:
A.txt B.txt C.txt
./NUMERIC:
1.txt 2.txt 3.txt
,该程序将foo
中的文件和ALPHABETIC
中的文件作为输入并输出某些内容。
我要创建一个规则,使得:如果NUMERIC
中的文件c
发生了变化,请在ALPHABETIC
上重新运行foo
,并在{{1}中运行每个文件}。如果c
中的文件NUMERIC
发生了变化,请在n
和NUMERIC
中的每个文件上重新运行foo
。
示例:n
发生变化。然后应该发生的是:
ALPHABETIC
让我们说A.txt
发生了变化。那应该发生的是
foo A.txt 1.txt
foo A.txt 2.txt
foo A.txt 3.txt
我尝试使用模式规则来执行此操作,但这没有用。
答案 0 :(得分:1)
由于make旨在管理从文件生成文件的构建系统,因此我们首先假设foo A.txt 1.txt
在主目录中生成名为A.1.txt
的文件。您可以尝试以下方法:
.PHONY: all
.DEFAULT_GOAL := all
ALPHA := $(patsubst ALPHABETIC/%.txt,%,$(wildcard ALPHABETIC/*.txt))
NUM := $(patsubst NUMERIC/%.txt,%,$(wildcard NUMERIC/*.txt))
# $(1): ALPHA
# $(2): NUM
define ALPHANUM_rule
$(1).$(2).txt: ALPHABETIC/$(1).txt NUMERIC/$(2).txt
@echo foo $(1).txt $(2).txt && \
touch $$@
all: $(1).$(2).txt
endef
$(foreach a,$(ALPHA),$(foreach n,$(NUM),$(eval $(call ALPHANUM_rule,$(a),$(n)))))
请注意使用echo
和touch
来模拟真实的foo
命令的效果。要理解的最重要的事情是foreach-eval-call
构造,包括某些$
符号需要加倍($$
)的原因。有关详细说明,请参见The eval Function中的GNU make manual。
演示(host>
是shell提示符):
host> make
foo B.txt 2.txt
foo B.txt 3.txt
foo B.txt 1.txt
foo A.txt 2.txt
foo A.txt 3.txt
foo A.txt 1.txt
foo C.txt 2.txt
foo C.txt 3.txt
foo C.txt 1.txt
host> make
make: Nothing to be done for 'all'.
host> touch NUMERIC/1.txt
host> make
foo B.txt 1.txt
foo A.txt 1.txt
foo C.txt 1.txt
host> make
make: Nothing to be done for 'all'.
host> touch ALPHABETIC/C.txt
host> make
foo C.txt 2.txt
foo C.txt 3.txt
foo C.txt 1.txt
host> make
make: Nothing to be done for 'all'.
但是如果foo A.txt 1.txt
不产生文件怎么办?在这种情况下,最简单的方法是始终生成空文件。我们将在一个单独的目录中创建它们,以便于清理:
.PHONY: all
.DEFAULT_GOAL := all
ALPHA := $(patsubst ALPHABETIC/%.txt,%,$(wildcard ALPHABETIC/*.txt))
NUM := $(patsubst NUMERIC/%.txt,%,$(wildcard NUMERIC/*.txt))
TAGSDIR := tags
$(TAGSDIR):
@mkdir -p $@
# $(1): ALPHA
# $(2): NUM
define ALPHANUM_rule
$(TAGSDIR)/$(1).$(2).txt: ALPHABETIC/$(1).txt NUMERIC/$(2).txt | $(TAGSDIR)
@echo foo $(1).txt $(2).txt && \
touch $$@
all: $(TAGSDIR)/$(1).$(2).txt
endef
$(foreach a,$(ALPHA),$(foreach n,$(NUM),$(eval $(call ALPHANUM_rule,$(a),$(n)))))
还有两件事要理解:
$(TAGSDIR)/A.1.txt...
)来跟踪已完成的操作以及何时执行。$(TAGSDIR)
用于确保包含空文件的目录是在使用前创建的,而不会在每次修改其内容时都强制重新构建。