簡體   English   中英

歧義重定向

[英]ambiguous redirection

我正在嘗試轉到當前目錄和所有子目錄,並在每個以.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;

我是bash的初學者,所以我認為我收到的一些錯誤可能是由於帶有循環的find語句引起的,但這是我得到的錯誤

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.

任何幫助將不勝感激=)

這是問題所在。 您的“回聲”將其釋放:

echo $f

輸出

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

我認為問題在於您在find命令中使用單引號(''),而不是反引號(``)。 因此,它並不是真正的運行查找,而只是擴展通配符。

您可能必須引述通配符,以便通過它來查找而不是由shell評估:

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

但是,腳本中存在幾個問題,如果您想多次使用它,應該解決這些問題。 參見ormaaj的答案

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

最好使用-exec 首先將此腳本寫入文件並使用chmod u+x scriptname腳本名:

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

for f in "$@"; 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
    ...

或者,如果您擁有Bash 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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM