GNU make 中 for 循环中的字符串替换
String substitution in a for loop in GNU make
假设列表 xl
和 yl
的项目数相同,并且现有字符串 s
。我想用 s
中 yl
的项目替代 xl
的项目。也就是说,对于 xl
中的每个 x
,我想调用 $(subst x,y,$(s))
,其中 y
是 yl
中的对应项。我试着做这样的事情:
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
假设列表 xl
和 yl
的项目数相同,并且现有字符串 s
。我想用 s
中 yl
的项目替代 xl
的项目。也就是说,对于 xl
中的每个 x
,我想调用 $(subst x,y,$(s))
,其中 y
是 yl
中的对应项。我试着做这样的事情:
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