2012-04-19 87 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