GNU make for 循环中的字符串替换

时间:2021-01-29 22:08:26

标签: makefile gnu-make

假设列表 xlyl 的项目数相同,并且现有字符串 s。我想用xlyl 的项目替换s 的项目。也就是说,对于x 中的每个xl,我想调用$(subst x,y,$(s)),其中yyl 中的对应项。我尝试做这样的事情:

ns := $(shell seq $(words $(xl)))
t := $(foreach i,$(ns),$(subst $(word $(i),$(xl)),$(word $(i),$(yl)),$(s))

但这不起作用,因为 foreach 扩展了 s every iteration 导致在 t 中重复。

获得我想要的结果的好方法是什么?谢谢。

3 个答案:

答案 0 :(得分:1)

使用递归宏生成数字序列并使用 evaĺ 进行文本替换,对于 GNU make 4.2.1:

s   := ABC def GHI bedeft ghi JKL xyz fnops
xl  := abc def ghi nop
yl  := jkl mno pqr (NOP)

# List natural numbers from 1 to length (< 1bn) of list in $1, void if $1 empty
seqn = $(strip $(if $(strip $1),$(call seqn,$(wordlist 2,999999999,$1)) $(words $1),))

ns := $(call seqn,$(patsubst %,x,$(xl)))
t := $(s)
$(foreach i,$(ns),\
    $(eval t:= $$(subst $(word $(i),$(xl)),$(word $(i),$(yl)),$$(t))))

.PHONY: all
all : ; $(foreach v,ns s t,$(info $(v): [$($(v))]))

来自 make --silent 的输出:

ns: [1 2 3 4]
s: [ABC def GHI bedeft ghi JKL xyz fnops]
t: [ABC mno GHI bemnot pqr JKL xyz f(NOP)s]

编辑

  • foreach 应该循环替换列表的索引,而不是目标字符串
  • 使用 seqn 调用 $(patsubst %,x,list) 宏以提高速度
  • 只有 $(subst …)$(t) 需要在 $$ stmt 中使用 eval 进行转义

答案 1 :(得分:1)

如果我理解正确,只是一个递归函数:

multi-subst = $(if $1,$(call multi-subst,$(wordlist 2,10000,$1),$(wordlist 2,10000,$2),$(subst $(firstword $1),$(firstword $2),$3)),$3)

s = abc dca acacd 
xl = a c
yl = 1 3
s_new := $(call multi-subst,$(xl),$(yl),$(s))

当然不可能替换包含空格的子字符串。有关字符串和列表的更多功能,您可能需要查看 gmtt

答案 2 :(得分:0)

我想,您必须分别对 s 的每个单词进行操作。

类似于:

t := $(foreach w,$(s),$(foreach i,$(ns),$(subst $(word $i,$(xl)),$(word $i,$(yl)),$w)))