2012-01-06 54 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到福爾酒吧其他可執行文件