2017-07-03 31 views
0

我试图在Make目标中用冒号分隔值拆分字符串。拆分制定规则中的字符串

当我尝试在使用for循环,eval,shell的目标配方中拆分字符串时,我得到空白值。在那时我使用shell命令将字符串拆分到目标结果之外是正面的。

任何人都可以帮助我修复目标配方。

下面是片段。

notebooks=new:e7e45d89-94cc-4783-86c5-2236d9904a24 test:2af1d689-98c3-48f2-984d-2ea21c5135dd 
j=new:e7e45d89-94cc-4783-86c5-2236d9904a24 
f1=$(shell echo $j | cut -d: -f 1) 
test1: 
    @for i in $(notebooks); \ 
    do \ 
     $(eval f=$(shell echo $i | cut -d: -f 1)) \ 
     $(eval fid=$(shell echo $i | cut -d: -f 2)) \ 
     echo $(f) $(fid) $(f1) ;\ 
    done 

输出是

new 
new 

鉴于期望的输出是

new e7e45d89-94cc-4783-86c5-2236d9904a24 new 
test 2af1d689-98c3-48f2-984d-2ea21c5135dd new 

回答

3

这是一个关于生成文件中最常见的混乱看来:所述配方之间的区别这是写在壳语法和构造。

使作品的方式是全部使配方中的构造(变量和函数)首先由make评估,然后将生成的扩展字符串传递给shell并由shell执行。

在你的例子中,你正在尝试使用一个包含make变量和函数的shell脚本循环:这不起作用(shell,它是一个新分叉的进程,要求重新扩展一些值基于一个shell变量)

化妆时要运行这个食谱:

@for i in $(notebooks); \ 
do \ 
    $(eval f=$(shell echo $i | cut -d: -f 1)) \ 
    $(eval fid=$(shell echo $i | cut -d: -f 2)) \ 
    echo $(f) $(fid) $(f1) ;\ 
done 

它首先展开所有makefile的变量和函数。记住它只是在这里扩展一个字符串,它不运行一个shell,所以没有shell命令被调用。前两行扩大这样的:

@for i in new:e7e45d89-94cc-4783-86c5-2236d9904a24 test:2af1d689-98c3-48f2-984d-2ea21c5135dd; \ 
do \ 

那么接下来的扩展:

$(eval f=$(shell echo $i | cut -d: -f 1)) \ 

这里$i只是一个make变量i,你从来没有设置,因此它是空的。所以要运行这个shell命令:

echo | cut -d: -f 1 

这将产生什么,所以$(eval f=)被扩大,使变量f设置为空字符串。

同样这一行:

$(eval fid=$(shell echo $i | cut -d: -f 2)) \ 

fid为空字符串。

那么这一行扩大

echo $(f) $(fid) $(f1) ;\ 

其扩展为:

echo new ;\ 

因为只有f1具有任何价值在这里。最后的最后一行:

done 

所以,在这一切之后扩展,传递给要运行外壳的字符串是:

@for i in new:e7e45d89-94cc-4783-86c5-2236d9904a24 test:2af1d689-98c3-48f2-984d-2ea21c5135dd; \ 
do \ 
    echo new; \ 
done 

绝对没有必要使用$(shell ...)的食谱;你已经在一个外壳,为什么你需要另一个?同样,你不需要eval来设置make变量,你需要使用shell变量。

写你的食谱是这样的:

@for i in $(notebooks); \ 
do \ 
    f=`echo $$i | cut -d: -f 1`; \ 
    fid=`echo $$i | cut -d: -f 2`; \ 
    echo $$f $$fid $(f1) ;\ 
done 
+0

感谢@MadScientist的解释。 – user3273016