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

时间:2018-07-18 15:05:21

标签: string bash makefile split gnu-make

在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##*:}),但这失败了,因为字符串似乎无法正确终止。

3 个答案:

答案 0 :(得分:2)

如果foo是一个make变量

来自Text functions sectionGNU make manual

  

$(subst from,to,text)对文本进行文本替换    text :每次出现 from 都会替换为 to 。结果是   代替了函数调用。

所以:

$(subst :, ,$(foo))

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

  

$(lastword names…)参数名称被视为一系列   名称,用空格分隔。该值是   系列。

所以:

$(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. 在将配方传递到外壳之前,先执行make的第一个扩展来保护配方的$符号,
  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

答案 1 :(得分:0)

如果您使用double dollar symbol,则可以逃脱美元,然后美元可以将其传递到外壳中。

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

答案 2 :(得分:0)

我知道这个问题是GNU make的问题,但是我想展示一下BSD make中的简单程度:

FOO=1:2:3:4:5

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

测试:

$ make
5

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

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