2012-04-19 120 views
0

我試圖去當前目錄和所有子direcotires,並添加一些註釋到,在.SQL曖昧重定向

繼承人結束代碼

HEADER="--SQL HEADER" 

for f in 'find . -name *.sql'; 
do 
     echo $f 
     echo -e $HEADER > $f.tmp; 
     FNAME=${f//\//_/}; 
     echo -e "\n\n--MORE ANNOTATIONS ${FNAME%.*}:1" >> $f.tmp; 
     cat $f >> $f.tmp; 
     mv $f.tmp $f; 
     rm $f.tmp 
done; 

IM A的片段每個文件初學者在打擊,所以我覺得有些錯誤的即時得到可能是由於與環 查找聲明,但這是錯誤我得到

find . -name X.sql A.sql W.sql E.sql S.sql 
./annotate.sh: line 6: $f.tmp: ambiguous redirect 
./annotate.sh: line 8: $f.tmp: ambiguous redirect 
./annotate.sh: line 9: $f.tmp: ambiguous redirect 
mv: invalid option -- n 
Try `mv --help' for more information. 
rm: invalid option -- n 
Try `rm --help' for more information. 

任何幫助將不勝讚賞=)

回答

3

這是問題所在。您的 「回聲」 使得它:

echo $f 

輸出

find . -name X.sql A.sql W.sql E.sql S.sql 

我認爲這個問題是你有直的單引號( '')在find命令,而不是反引號(``)。所以它不是真的在找,而只是擴展通配符。

您可能需要引用通配符所以它被傳遞給找到,而不是由shell評價:

for f in `find . -name \*.sql`; 

不過,也有在腳本中,有幾個問題,如果你想使用你應該解決它不止一次。見ormaaj's answer

+5

+1,避免混淆(並允許嵌套作爲獎金),這是更好地使用'$(命令)'的形式,而不是反引號變種'\'命令\ ''。 – 2012-04-19 19:28:19

+1

不好...不要推薦使用'for'和反引號來迭代文件(正如所指出的,使用'$()')。不會-1,因爲你確實指出了最直接的問題。 – ormaaj 2012-04-19 21:40:29

+0

正確,謝謝你指出這一點。我只是回答這個問題,而不是試圖教導如何編寫shell腳本。 – theglauber 2012-04-19 21:46:29

2

正如已經指出的那樣,問題在於find沒有實際執行。但是,這種模式是非常錯誤的。使用for循環對使用命令替換髮生的任何事情循環使用不起作用,因爲將輸出拆分爲單詞需要單詞拆分,這需要不引用,即使禁用了路徑名擴展,因爲文件名可以包含換行符,這也是一個問題。

優選地,使用-exec。首先寫這個腳本文件和chmod u+x scriptname

#!/usr/bin/env bash 
header="--SQL HEADER" 

for f in "[email protected]"; do 
    echo "$f" >&2 
    fname=${f//\//_/} 

    cat - "$f" <<EOF >"$f.tmp" 
    ${header}$'\n\n' 
    --MORE ANNOTATIONS ${fname%.*}:1 
    EOF 

    mv "$f.tmp" "$f" 
done 

然後運行find這樣的:

find . -name '*.sql' -exec scriptname {} + 

或者,(假設這是一個最近的Bash的版本),使用globstar並沒有find(如果你願意,ksh也有類似的功能)。這可能會比較慢,具體取決於作業 - shell必須預先生成文件列表。

#!/usr/bin/env bash 
shopt -s globstar 

for f in ./**/*.sql; do 
    ... 

或者,如果你有擊4和必要的GNU工具的系統,使用-print0

find . -name '*.sql' -print0 | while IFS= read -rd '' f; do 
    # <body of the above for loop here> 
done 

參見:http://mywiki.wooledge.org/UsingFind