You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Makefile目标中正确使用Bash正则表达式?

这个问题我太熟了!Makefile的语法规则和Bash确实有不少冲突点,尤其是$符号的处理和默认shell环境的差异,我来给你拆解正确的写法:

首先得明确两个核心问题:

  1. Make默认用/bin/sh执行命令,而[[ =~ ]]是Bash独有的正则匹配语法,所以必须强制用Bash来跑你的逻辑;
  2. Make里的$是变量引用的标记,所以所有要传给Bash的$都得转义成$$,不然会被Make提前解析成自己的变量。

下面是完整的可运行Makefile写法:

# 先指定用Bash执行所有recipe,避免sh不支持正则语法
SHELL := /bin/bash

my-target:
	MY_STRING="FirstName-LastName-Gender-Age" ; \
	MY_REGEX="([^-]+)-([^-]+)$$" ; \
	if [[ $$MY_STRING =~ $$MY_REGEX ]]; then \
		echo "完整匹配: $${BASH_REMATCH[0]}" ; \
		echo "第一组(倒数第二个字段): $${BASH_REMATCH[1]}" ; \
		echo "第二组(最后一个字段): $${BASH_REMATCH[2]}" ; \
	fi

给你逐个解释关键细节:

  • SHELL := /bin/bash:这行一定要加,告诉Make放弃默认的sh,改用Bash执行后续命令,不然[[ =~ ]]会直接报错;
  • MY_REGEX里的$写成$$:原本Bash正则里的$是行尾锚点,但Make会把单个$当成变量引用,所以必须转义成$$才能让Bash识别;
  • $$MY_STRING、$$MY_REGEX:同理,Bash变量前的$必须转义,不然Make会试图去找名为MY_STRING的Make变量(而不是Bash变量);
  • $${BASH_REMATCH[...]}:这里要写成两层转义,因为${BASH_REMATCH[0]}是Bash的数组引用,外层的$$让Make解析成单个$,最终传给Bash的就是正确的${BASH_REMATCH[0]};
  • 每行末尾的\:Make的recipe里每行都是单独的shell进程,用\换行可以把所有命令放到同一个shell进程里,保证变量能跨命令使用。

如果你喜欢更紧凑的写法,也可以把逻辑打包成单个bash命令:

my-target:
	@bash -c 'MY_STRING="FirstName-LastName-Gender-Age"; MY_REGEX="([^-]+)-([^-]+)$"; if [[ $$MY_STRING =~ $$MY_REGEX ]]; then echo "匹配结果: $${BASH_REMATCH[0]}, 分组: $${BASH_REMATCH[1]}, $${BASH_REMATCH[2]}"; fi'

这种写法里同样要注意转义$,而且用@开头可以避免Make打印出完整的命令行,只输出你想要的结果。

内容的提问来源于stack exchange,提问作者code

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 03:39:03