查找 /foo/bar* 而不是查找 /foo -name "bar*"

  • 本文关键字:查找 bar foo -name bash
  • 更新时间 :
  • 英文 :


通常建议使用

find /foo -name "bar*"

以在CCD_ 2中查找以CCD_ 1开头的所有文件。使用不是更简单吗

find /foo/bar*

我知道bash在上一个例子中扩展了/foo/bar*,而不是find本身,但这其中有风险吗?

我的用例是,我想将find的命令存储在一个变量中,例如

FINDSTRING='/foo -name "bar*"'
FILES=`find $FINDSTRING`

不起作用,或者

FINDSTRING='/foo -name bar*'
FILES=`find $FINDSTRING`

如果当前目录中有bar*文件,但不起作用

FINDSTRING='/foo/bar*'
FILES=`find $FINDSTRING`

确实有效。

使用数组将选项存储到命令,而不是平面字符串:

find_options=( /foo -name "bar*" )
files=$( find "${find_options[@]}" )

如果文件名包含空白,那么尝试将文件列表存储在字符串中还会有其他问题,但这是另一个问题。

与其将整个find命令存储在一个变量中,不如考虑将路径和glob模式存储在这样的变量中:

fpath='/foo'
fname='bar*'

然后运行查找命令作为:

find "$fpath" -name "$fname"
FINDSTRING='/foo -name bar*'
FILES=`find $FINDSTRING`

在本例中,bash扩展通配符(*)而不是bar0。CCD_ 11尝试将文件列表评估为名称模式文件。所以它不起作用。。。

否则,-name选项允许我们使用特定的名称文件模式,例如:

sudo find / -name "[0-9]*"

如果当前目录中有一个bar*文件,但

您可以通过在参数周围使用单引号来防止Bash扩展FINDSTRING中的*来解决此问题:

FINDSTRING="/foo -name 'bar*'"

不要让Bash进行扩展(如果这样做,使用find有什么意义,因为Bash已经生成了匹配文件的列表?)

find /foo/bar*只搜索/foo目录顶层以"bar"开头的文件名。例如,如果/foo/quux/bar.txt存在,find /foo -name "bar*"会找到它,但find /foo/bar*不会。

现在,关于将命令存储在变量中,简单的答案是不能(至少在普通变量中)。有一些类似于将其存储在变量中的选项,但应该使用哪一个取决于为什么要将其存储到变量中。BashFAQ#50:我试图在变量中放入一个命令,但复杂的情况总是失败!涵盖了这一点,但这里是简短的摘要。

  • 如果在执行命令之前没有充分的理由将命令存储在变量中,那么就不要。存储&检索命令可能会很混乱,如果没有充分的理由,就跳过整个混乱,直接执行命令。

  • 如果需要动态构建命令,可以将命令(或仅其参数)存储在数组中(正如chepner所建议的):

    find_options=(/foo -name "bar*")
    files="$(find "${find_options[@]}")"
    

    正如chepner也指出的,如果文件名中有空格,这将失败。您还应该将文件名存储为数组:

    find_options=(/foo -name "bar*")
    files=()
    while IFS= read -r -d '' file; do
    files+=("file")
    done < <(find "${find_options[@]}")
    dostuffwith "${files[@]}"
    

    (请参阅BashFAQ#20:如何找到并安全地处理包含换行符、空格或两者兼有的文件名?)

  • 如果你只想重复使用命令,而不是每次都写出来,你可以把命令变成一个函数:

    find_bar() {
    find /foo -name "bar*"
    }
    files=()
    while IFS= read -r -d '' file; do
    files+=("file")
    done < <(find_bar)
    dostuffwith "${files[@]}"
    

最新更新