2012-01-06 53 views
7

使用for循环,我想用一个循环来找到一些文件并重新命名:如何化妆配方

for i in `find [email protected] -name *_cu.*`;do mv $i "$(echo $i|sed s/_cu//)" 
    done 

这个作品在外壳。但是我怎么能在makefile配方中做到这一点?

+1

关 - 话题:在find命令中引用''* _cu。*''是个好主意,正如你希望通过find扩展的那样,而不是调用find的shell。 – 2012-01-06 13:41:27

+0

这个命令的触发不能用这个'$ @'作为你的目标。 – reinierpost 2012-01-06 20:59:03

回答

28

有两个主要的事情是,你需要把不平凡的贝壳碎片进入化妆配方时,就知道:(!当然)

  1. 命令食谱中是执行一次一个,其中命令的含义是“配方中的制表符前缀行”,可能分散在多个带反斜杠的生成文件行中。

    因此,您的shell片段必须全部写在一个(可能是反斜杠)行上。此外,它作为单行有效地呈现给shell(反斜杠 - 新行不是简单的换行符,因此不用作shell的命令终止符),因此必须在语法上正确。

  2. 两个shell变量,使变量由美元符号([email protected]$i)推出,所以你需要通过编写他们作为$$i隐藏从让你的shell变量。 (更准确地说,任何美元符号要由壳通过写它作为$$看到必须从make进行转义。)

通常在一个shell脚本,你会写在不同的行分开的命令,但在这里您实际上只能得到一行,因此必须用分号分隔各个shell命令。把所有这一切共同为您的示例产生:

foo: bar 
    for i in `find [email protected] -name *_cu.*`; do mv $$i "$$(echo $$i|sed s/_cu//)"; done 

或等价:

foo: bar 
    for i in `find [email protected] -name *_cu.*`; do  \ 
     mv $$i "$$(echo $$i|sed s/_cu//)"; \ 
    done 

注意后者,即使它奠定了可读取几行,需要同样的谨慎使用分号来保持壳高兴。

+0

出于好奇,你为什么要离开'$ @'完好无损?它在Makefiles中有没有特殊的含义?在shell中,它扩展为脚本参数列表... – fge 2012-01-06 13:03:21

+0

@fge:make将命令传递给shell,就好像通过system()一样,所以没有shell脚本参数,shell的'$ @'会永远是空的。 OTOH make的'$ @'指的是规则的目标(这里_foo_),我认为这是目标。 – 2012-01-06 13:37:46

+1

嗯,我不太确定,从OP的片段似乎确实是从一个shell脚本 – fge 2012-01-06 13:38:40

0

我发现这个有用的,试图用for循环建立多个文件:

PROGRAMS = foo bar other 

.PHONY all 
all: $(PROGRAMS) 
$(PROGRAMS): 
    gcc -o [email protected] [email protected] 

它将编译foo.c的,bar.c,other.c到福尔酒吧其他可执行文件