使拆分字符串获取最后一个元素

make split string get last element

在bash中我可以拆分类似于 How to split a string in shell and get the last field

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

如何在 makefile 中实现与 make 类似的功能?我找到的任何解决方案都比 bash 吊坠复杂得多。

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

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

例如echo $${foo##*.} 在你的 makefile.

里面

如果foo是make变量

来自Text functions section of the GNU make manual:

$(subst from,to,text) performs a textual replacement on the text text: each occurrence of from is replaced by to. The result is substituted for the function call.

所以:

$(subst :, ,$(foo))

通过用 space 替换所有 : 来拆分 make 变量 foo 的内容。仍然来自 GNU make 手册:

$(lastword names…) The argument names is regarded as a series of names, separated by whitespace. The value is the last name in the series.

所以:

$(lastword $(subst :, ,$(foo)))

应该做你想做的。演示(host>是shell提示):

host> cat Makefile
foo := 1:2:3:4:5

all:
    $(info $(lastword $(subst :, ,$(foo))))
host> make
5

如果 foo 是一个 shell 变量

你必须:

  1. 在将配方传递给 shell、
  2. 之前,保护配方的 $ 标志免受 make 执行的第一次扩展
  3. 考虑到您的配方的每一行都由单独的 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

我知道这个问题与 GNU make 相关,但我想展示 BSD make:

是多么简单
FOO=1:2:3:4:5

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

测试:

$ make
5

说明(man make):${FOO:C/.*://}中的:C...命名为变量修饰符:C 修饰符的作用类似于 seds 命令。在这种情况下,它会更改由 sed 类表达式定义的变量 ${FOO} 中的所有 word:所有字符和尾随冒号都替换为空(也称为删除它)。

请注意 .*: 表达式是贪婪的(像往常一样 - .* 可以包含许多冒号)。