Filter Makefile:如何在多个通配符上应用等效过滤器

Filter Makefile:如何在多个通配符上应用等效过滤器,filter,makefile,wildcard,Filter,Makefile,Wildcard,我正在写一个Makefile,我被一个过滤器函数限制卡住了。 实际上,筛选器只接受一个通配符 我想做的是: 我有一个列表a文件,一些匹配regexp blablabla,一些不匹配。但为此我需要2个通配符,因此我不能使用过滤器函数 我想将我的原始列表分为两个列表,一个包含所有包含blabla字符串的元素(过滤器等价物),另一个包含不匹配的元素(过滤掉等价物) 感谢您的帮助。Make最大的缺点之一是处理正则表达式的能力差。函数过滤器和筛选出不能在单词的中间找到“旧”。我建议这样做: NOT_OLD

我正在写一个Makefile,我被一个过滤器函数限制卡住了。 实际上,筛选器只接受一个通配符

我想做的是: 我有一个列表a文件,一些匹配regexp blablabla,一些不匹配。但为此我需要2个通配符,因此我不能使用过滤器函数

我想将我的原始列表分为两个列表,一个包含所有包含blabla字符串的元素(过滤器等价物),另一个包含不匹配的元素(过滤掉等价物)


感谢您的帮助。

Make最大的缺点之一是处理正则表达式的能力差。函数<代码>过滤器和<代码>筛选出不能在单词的中间找到“旧”。我建议这样做:

NOT_OLD = $(shell echo $(LIST) | sed 's/[^ ]*old[^ ]* *//g')
OLD = $(filter-out $(NOT_OLD), $(LIST))

您可以利用shell更高级的字符串处理功能。假设您有
bash
,您可以在
makefile
中使用以下内容:

LIST := a_old_tt x_old_da a_new_da q_ty_we
LIST_NOT_OLD := $(shell l=($(LIST)); echo $${l[@]//*old*})
LIST_OLD := $(filter-out $(LIST_NOT_OLD),$(LIST))

您可以在中找到bash字符串替换机制的解释。在shell调用中保留
$
符号需要双
$

您可以在不运行任何外部命令的情况下执行此操作。定义两个宏

containing = $(foreach v,$2,$(if $(findstring $1,$v),$v))
not-containing = $(foreach v,$2,$(if $(findstring $1,$v),,$v))
现在你可以做了

LIST := a_old_tt x_old_da a_new_da q_ty_we
LIST_OLD := $(call containing,old,$(LIST))
LIST_NOT_OLD := $(call not-containing,old,$(LIST))

您使用的是GNU make还是其他变体?并显示您当前的代码,不清楚问题出在哪里。请提供文件、筛选器表达式和所需结果的示例列表。按照您现在描述的方式,我不清楚为什么
$(filter…
$(filter out…
功能对您来说不够好。谢谢您的回复。我正在使用gnu make。我没有代码要显示,因为我不知道如何编写它。假设我有列表=a_old_tt x_old_da a_new_da q_ty_we。我想对列表内容进行排序:LIST_OLD包含包含表达式OLD的列表的所有成员(在我的示例中是a_OLD_tt和x_OLD_da),LIST_NOT_OLD包含不包含表达式OLD的列表的所有成员(在我的示例中是a_new_da q_ty_we)。+1,看起来合理,我个人也会用同样的方法来实现它。如果你需要完整的正则表达式来计算“包含”布尔值,那么它是有限的,但它适用于这种特殊情况。我个人不会担心外部命令,因为Make的性能/内部循环很可能在目标中,在build/compile命令中。当然,正如Beta在回答中所说,
Make
根本无法处理正则表达式,所以如果您需要它们(但OP不需要),显然您不能使用这个答案。对此问题的第一反应通常是拿出大炮并调用外部命令来进行匹配,但正如本例所示,这可能是一种巨大的过度杀伤力。为了便于移植和提高速度,我尽量避免运行外部命令。在基于make的大型构建系统中,我已经看到了通过消除不必要的外部命令而获得的巨大性能提升。这对于我来说不适用于使用%作为目标依赖项列表的一部分。它只是一个空字符串。也许它正在搜索文字%符号?