通常建议使用
find /foo -name "bar*"
在bar
中查找以/foo
开头的所有文件。使用
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`
确实有效。
答案 0 :(得分:4)
使用数组存储命令的选项,而不是扁平字符串:
find_options=( /foo -name "bar*" )
files=$( find "${find_options[@]}" )
如果这些文件名包含空格,尝试将文件列表存储在字符串中还有其他问题,但这是另一个问题。
答案 1 :(得分:2)
不是将整个find
命令存储在变量中,而是考虑在这样的变量中存储路径和glob模式:
fpath='/foo'
fname='bar*'
然后运行您的find命令:
find "$fpath" -name "$fname"
答案 2 :(得分:0)
FINDSTRING='/foo -name bar*' FILES=`find $FINDSTRING`
在此示例中,bash
正在展开通配符(*
)而不是find
。 find
因此尝试将文件列表评估为名称模式文件。所以它不起作用......
否则,-name
选项允许我们使用特定模式的名称文件,例如:
sudo find / -name "[0-9]*"
答案 3 :(得分:0)
如果当前目录中有bar *文件,则不起作用,但
您可以通过在参数周围使用单引号来阻止Bash扩展*
中的FINDSTRING
来解决此问题:
FINDSTRING="/foo -name 'bar*'"
不要让Bash进行扩展(如果你这样做,那么使用find
的重点是什么,因为Bash已经生成了匹配文件列表?)
答案 4 :(得分:0)
find /foo/bar*
仅搜索/ foo目录顶层以“bar”开头的文件名。例如,如果/foo/quux/bar.txt存在,find /foo -name "bar*"
会找到它,但find /foo/bar*
不会找到它。
现在,至于将命令存储在变量中,简短的答案是你不能(至少在一个普通的变量中)。有一些选项可以执行类似于将其存储在变量中的选项,但是您应该使用哪个选项取决于为什么要将其存储在变量中。 BashFAQ #50: I'm trying to put a command in a variable, but the complex cases always fail!涵盖了这一点,但这里是简短摘要。
如果您没有充分的理由在执行变量之前将命令存储在变量中,那么只需不。存储&检索命令可能很麻烦,如果没有充分理由可以跳过整个混乱并直接执行命令。
如果需要动态构建命令,可以将命令(或只是其参数)存储在数组中(如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: How can I find and safely handle file names containing newlines, spaces or both?。)
如果您只是想重复使用该命令而不是每次都写出来,可以将命令转换为函数:
find_bar() {
find /foo -name "bar*"
}
files=()
while IFS= read -r -d '' file; do
files+=("file")
done < <(find_bar)
dostuffwith "${files[@]}"