find:如果沒有指定文件,則不執行任何操作

find:如果沒有指定文件,則不執行任何操作

我想find對某些檔案名稱呼叫 use 。

find $(do_something to find filenames) -print0 | xargs -r0 ls -ld

如果不傳回任何內容,則會中斷$(do_something to find filenames):find 指令開始進行遞迴搜尋。

如果沒有明確的檔案名稱/目錄名稱作為參數,有沒有辦法告訴 find 不執行任何操作?

答案1

有了zsh,我會這樣做:

files=($(do_something to find filenames))
(($#files)) && find $files ...

tcsh

set files=(`do_something to find filenames`)
if ($#files) find $files:q ...

bash,mkshksh93,

set -f; files=($(do_something to find filenames))
((${#files[@]})) && find "${files[@]}" ...

POSIXly:

set -f; set -- $(do_something to find filenames)
[ "$#" -gt 0 ] && find "$@" ...

(在 bash 和其他 POSIX shell 中,$(...)分割($IFS預設在:空格、製表符和換行符上),但也會對結果單字執行通配,我不希望您在這裡需要,因此set -f. 其他shell ((t)csh 、zsh、fish、rc、es...)沒有這個問題)。

答案2

這樣做怎麼樣:

paths=$(do_something to find filenames)
if [ "$paths" ]; then
    find "$paths" ...
fi

這與find實現無關。

請注意,find "$paths"使用多個路徑名會導致問題。如果路徑名不包含空格,您可以使用:find $paths,否則,一個可行的替代方法是此函數:

dofind() {
    set -f
    set -- $(do_something to find filenames)
    if [ $# -gt 0 ]; then
        find "$@" ...
    fi
    set +f
}

它會停用檔案通配,然後用於set --設定 shell arg 向量。這適用於任何 POSIX shell。

答案3

您可以提供find一個額外的、不存在的目錄來啟動:

find " " $(do_something to find filenames) -print0 | xargs -r0 ls -ld

為了使這個整潔, dropfind的錯誤輸出:

find " " $(do_something to find filenames) -print0 2>/dev/null | xargs -r0 ls -ld

(但是如果發生另一個錯誤,您將不會注意到...)。

do_something to find filenames輸出檔名時,find會抱怨" "但仍會處理命令列的其餘部分。當沒有檔案名稱輸出時,find將再次抱怨" "但不會添加其預設..

答案4

zsh(以及大多數非 Bourne 派生的 shell)中,當(或全部取決於外殼)全域不展開,命令被中止。

$(do_something to find filenames)不是一個 glob,但您可以透過在 中附加一個 glob 限定符來使其成為一個 glob zsh

 find $(do_something to find filenames)(#q) -print0...

上面, that (#q)(一個空的 glob 限定符,因此不執行任何其他操作)被附加到 的輸出分割的最後一個單字上do_something to find filenames,因此如果該命令不產生(或空白)輸出,則該命令將被中止,但如果最後一個字(僅最後一個字)不會解析為現有路徑。您可以將其套用於該分割產生的每個單字(以便如果這些單字中的任何一個未解析為現有文件,則命令將中止):

 find ${^$(do_something to find filenames)}(#q) -print0...

相關內容