将分割字符串获取最后一个元素

3

在bash中,我可以类似于如何在shell中分割字符串并获取最后一个字段的方法来分割字符串。

foo=1:2:3:4:5
echo ${foo##*:}

我该如何在makefile中实现类似于bash的功能呢?我找到的所有解决方案都比bash版本复杂得多。

我尝试使用以下代码:$(shell ${foo##*:}),但是它失败了,因为字符串似乎没有正确终止。


这是一个字符串还是一个变量在makefile中?如果是一个变量,那么你可以引用该文件并回显该变量。请详细解释一下,并给出你所指的makefile部分的示例。此外,你想改变那个文件还是只是以某种方式使用输出? - py9
1
@GeorgHeiler 所以,这是一个 make 变量,而不是 shell 变量。在你的例子中 echo $(lastword $(subst /, ,$(myvar))) 实现了你想要的效果(详见我的回答)。 - Renaud Pacalet
请问您是否觉得阅读此处的功能(https://github.com/markpiffer/gmtt#call-glob-matchstringpattern)也太过复杂难懂了呢? - Vroomfondel
请仅返回翻译文本:查看已接受的答案 - 不要 - Georg Heiler
嗯,我想你在我的问题中错过了https://github.com/markpiffer/gmtt#call-glob-matchstringpattern的链接? - Vroomfondel
显示剩余2条评论
3个回答

9

如果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变量

您必须:

  1. 保护您的配方中的$符号,使其不受make在将配方传递给shell之前执行的第一次扩展影响,
  2. 注意您的每个配方行都由单独的shell执行:如果您在一行上定义了一个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

0

如果你使用双美元符号,你将转义美元符号,然后可以将其传递给shell。

例如,在你的makefile中使用echo $${foo##*.}


0

我知道这个问题与 GNU make 相关,但我想展示在 BSD make 中它有多简单:

FOO=1:2:3:4:5

all:
    @echo ${FOO:C/.*://}

还有测试:

$ make
5

解释(人造):在${FOO:C/.*://}中的:C...被称为变量修饰符:C修饰符的工作方式类似于seds命令。在这种情况下,它通过sed样式表达式更改由${FOO}定义的变量单词:所有字符和尾随冒号都被替换为空(也就是删除它)。

请注意,.*:表达式是贪婪的(通常情况下-.*可以包含许多冒号)。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接