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...

相关内容