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

String substitution in a for loop in GNU make

假设列表 xlyl 的项目数相同,并且现有字符串 s。我想用 syl 的项目替代 xl 的项目。也就是说,对于 xl 中的每个 x,我想调用 $(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.

中的重复

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

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

类似于:

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

使用递归宏生成数字序列和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 , void if  empty
seqn = $(strip $(if $(strip ),$(call seqn,$(wordlist 2,999999999,)) $(words ),))

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

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

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

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

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