如何使用make保留最后一个字符串具有相同的前缀?

问题描述 投票:0回答:2

举个例子,假设我有字符串:

FILES=APPLE=A PHOTO=P APPALE=APP NUMBER=N APPALE=APPL APPALE=APPLE LARGE=L PHOTO=PHO

我想要得到的是以下字符串:

FILES=NUMBER=N APPALE=APPLE LARGE=L PHOTO=PHO

我尝试过使用过滤器,但似乎没有一个提供很好的解决方案。

define uniq
$(eval _set :=)\
$(strip $(foreach w,$(1), $(eval _first := $(word 1,$(subst $(2),$(space),$(w))))\
    $(if $(filter $(_set ),$(_first)),$(w),\
        $(eval _set += $(_first)))))\
$(eval _set :=)\
$(eval _first:=)
endef
makefile gnu-make
2个回答
0
投票

解决方案如下:

# $1 values, $2 results
# expands to results
sift = $(strip $(if $1,\
  $(call sift,$(wordlist 2,$(words $1),$1),\
    $(strip $(if $(filter $(firstword $1)%,$2),$2,\
      $(foreach x,$2,$(if $(filter $x%,$(firstword $1)),,$x)) \
      $(firstword $1)))),\
  $2))

FILES = APPLE=A PHOTO=P APPALE=APPLE NUMBER=N APPALE=APPL APPALE=APP LARGE=L PHOTO=PHO

RESULTS = $(call sift,$(FILES))

all:;@echo '$(RESULTS)'

和:

$ make
APPLE=A APPALE=APPLE NUMBER=N LARGE=L PHOTO=PHO

使用 make 函数的关键是,如果你考虑递归而不是循环,它会容易得多。

我应该指出,这并不关心单词的结构;而是关心单词的结构。也就是说,这里并没有特别对待

=
。这只是另一个字母,例如
a
b


0
投票
include gmtt/gmtt.mk

TEXT := FILES=APPLE=1      PHOTO=10      APPALE=A NUMBER=3 APPALE=240 APPALE=160 LARGE=false PHOTO=true

compile-vars = $(eval $(subst $(space),$(newline),$(patsubst %,****%,$(1))))$(foreach v,$(filter ****%,$(.VARIABLES)),$(patsubst ****%,%,$(v))=$($(v)))$(foreach v,$(filter ****%,$(.VARIABLES)),$(eval undefine $(v)))


$(info $(TEXT))

COMPILED := $(call compile-vars,$(TEXT))

$(info $(COMPILED))

我们滥用

make
本身内部的变量存储来执行覆盖赋值。但请注意,变量的顺序不会保留,
FILES
可能会出现在列表的最后。

gmtt 只适用于

space
newline

© www.soinside.com 2019 - 2024. All rights reserved.