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

Makefile变量扩展中的多后缀截断问题求助

解决Makefile中批量截断多个后缀的问题

我最近在Makefile里碰到个头疼的问题:需要给一批包名批量移除不同的后缀(比如OPT1、OPT2),折腾了好几种写法都没成功,好在最后找到了解决办法,分享给大家。

先说说我的场景:

  • 已经在Makefile里指定了SHELL=/bin/bash强制使用bash
  • 变量PKG_LIST存着一堆文件夹名,比如packageFsOPT1 packageAdc packageMemOPT2,部分名称带OPT1/OPT2后缀,部分不带
  • 存在一个tmp目录,里面包含packageFs、packageAdc这类不带后缀的子文件夹

最开始处理单个后缀时,这段代码能正常工作,顺利截断OPT1后缀:

for pkg in $(PKG_LIST) ; do \
  cd tmp && tar xzf $$pkg-$(MAJOR).$(MINOR).$(TARGET).tar.gz tmp ; \
  cp -a tmp/$${pkg%OPT1} $(DEST_DIR) ; \
done

但要同时处理OPT1和OPT2时就卡壳了:

  • 我试了cp -a tmp/$${pkg%+(OPT1|OPT2)} $(DEST_DIR),直接在控制台测试是有效的,但放到Makefile里完全没作用,后缀没被截断,导致找不到目标文件夹复制失败
  • 又尝试把截断后的结果存到变量里:pkg_stripped=$(shell echo ${pkg%+(OPT1|OPT2)}),结果这个变量直接为空,还是不行

可行解决方案

方案一:开启bash扩展通配符

Makefile默认没开启bash的extglob扩展通配符,所以+(...)这种写法不生效,我们只需要在循环里手动开启即可:

for pkg in $(PKG_LIST) ; do \
  cd tmp && tar xzf $$pkg-$(MAJOR).$(MINOR).$(TARGET).tar.gz tmp ; \
  shopt -s extglob ; \
  cp -a tmp/$${pkg%+(OPT1|OPT2)} $(DEST_DIR) ; \
done

方案二:用sed做字符串替换

如果觉得依赖bash扩展不太稳妥,也可以用sed来处理包名,不管是OPT1还是OPT2都能精准替换掉:

for pkg in $(PKG_LIST) ; do \
  cd tmp && tar xzf $$pkg-$(MAJOR).$(MINOR).$(TARGET).tar.gz tmp ; \
  pkg_stripped=$$(echo "$$pkg" | sed 's/OPT1$$\|OPT2$$//') ; \
  cp -a tmp/$$pkg_stripped $(DEST_DIR) ; \
done

这里sed的表达式s/OPT1$$\|OPT2$$//会匹配行尾的OPT1或OPT2,然后替换为空,完美实现后缀截断效果。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.28 18:57:41