通常建议使用
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
扩展通配符(*
)而不是bar
0。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[@]}"