在bash中,我可以类似于如何在shell中分割字符串并获取最后一个字段的方法来分割字符串。
foo=1:2:3:4:5
echo ${foo##*:}
我该如何在makefile中实现类似于bash的功能呢?我找到的所有解决方案都比bash版本复杂得多。
我尝试使用以下代码:$(shell ${foo##*:})
,但是它失败了,因为字符串似乎没有正确终止。
foo
是一个make变量来自GNU make手册的文本函数部分:
$(subst from,to,text)
在文本text中执行文本替换:将每个from替换为to。结果替换函数调用。
因此:
$(subst :, ,$(foo))
将make变量foo
的内容通过将所有:
替换为空格来分割。仍然来自GNU make手册:
$(lastword names…)
参数names被视为一系列由空格分隔的名称。该值是系列中的最后一个名称。
所以:
$(lastword $(subst :, ,$(foo)))
您希望的功能应该可以实现。以下是演示(host>
是命令行提示符):
host> cat Makefile
foo := 1:2:3:4:5
all:
$(info $(lastword $(subst :, ,$(foo))))
host> make
5
foo
是一个shell变量您必须:
$
符号,使其不受make在将配方传递给shell之前执行的第一次扩展影响,all:
@foo=1:2:3:4:5 && \
echo $${foo##*:}
应该按照您的要求进行操作:美元符号$
已经正确转义,这是一个单行代码(感谢尾随的\
)。演示:
host> cat Makefile
all:
@foo=1:2:3:4:5 && \
echo $${foo##*:}
host> make
5
我知道这个问题与 GNU make
相关,但我想展示在 BSD make
中它有多简单:
FOO=1:2:3:4:5
all:
@echo ${FOO:C/.*://}
还有测试:
$ make
5
解释(人造):在${FOO:C/.*://}
中的:C...
被称为变量修饰符。 :C
修饰符的工作方式类似于sed
的s
命令。在这种情况下,它通过sed
样式表达式更改由${FOO}
定义的变量单词:所有字符和尾随冒号都被替换为空(也就是删除它)。
请注意,.*:
表达式是贪婪的(通常情况下-.*
可以包含许多冒号)。
echo $(lastword $(subst /, ,$(myvar)))
实现了你想要的效果(详见我的回答)。 - Renaud Pacalet