我想用来find
在一组受通配符限制的文件夹中查找文件,但路径名中有空格。
从命令行,这很容易。以下示例均有效。
find te*/my\ files/more -print
find te*/'my files'/more -print
find te*/my' 'files/more -print
这些将在例如terminal/my files/more
和中找到文件tepid/my files/more
。
但是,我需要将其作为脚本的一部分;我需要的是这样的:
SEARCH='te*/my\ files/more'
find ${SEARCH} -print
不幸的是,无论我做什么,我似乎都无法find
在脚本中的命令中混合使用通配符和空格。上面的示例返回以下错误(请注意反斜杠意外加倍):
find: ‘te*/my\\’: No such file or directory
find: ‘files/more’: No such file or directory
尝试使用引号也会失败。
SEARCH="te*/'my files'/more"
find ${SEARCH} -print
这将返回以下错误,忽略了引号的含义:
find: ‘te*/'my’: No such file or directory
find: ‘files'/more’: No such file or directory
再举一个例子。
SEARCH='te*/my files/more'
find ${SEARCH} -print
正如预期的那样:
find: ‘te*/my’: No such file or directory
find: ‘files/more’: No such file or directory
我尝试过的每个变体都会返回错误。
我有一个解决方法,它有潜在的危险,因为它会返回太多文件夹。我将所有空格转换为问号(单字符通配符),如下所示:
SEARCH='te*/my files/more'
SEARCH=${SEARCH// /?} # Convert every space to a question mark.
find ${SEARCH} -print
这相当于:
find te*/my?files/more -print
这不仅会返回正确的文件夹,还会返回terse/myxfiles/more
它不应该返回的 .
我怎样才能实现我想要做的事情?谷歌没有帮助我:(
完全相同的命令在脚本中应该可以正常工作:
如果你需要把它作为一个变量,它会变得有点复杂:
警告:
这样使用
eval
是不安全的,如果您的文件名可以包含某些字符,可能会导致执行任意且可能有害的代码。有关详细信息,请参阅bash FAQ 48。最好将路径作为参数传递:
另一种方法是完全避免
find
并使用 bash 的扩展通配特性和通配符:globstar
bash 选项允许您使用递归**
匹配:要使其 100% 像查找和包含点文件(隐藏文件)一样运行,请使用
您甚至
echo
可以直接使用它们而无需循环:数组呢?
(*)
扩展为与通配符匹配的数组。并"${SEARCH[@]}"
扩展为数组 ([@]
) 中的所有元素,每个元素都单独引用。后来,我意识到 find 本身应该能够做到这一点。就像是:
它现在有点过时但是,如果这可以帮助任何人解决这个问题,使用 RE 的整理符号
[[.space.]]
而不$SEARCH
在 find 命令行参数中引用变量,只要扩展路径名中没有特殊字符代替星号,它就可以工作。给出以下结果:
为防止全局化不需要的字符,可以将星号 (
*
) 替换为任何整理元素(字符):给出以下结果:
请注意,要缩短行,
[.hyphen.]
可以用[.-.]
or替换-
, 也可以用or[.underscore.]
替换。[._.]
_
\
为了便于阅读,我自己添加了带有反斜杠 ( ) 的截断行。我终于找到了答案。
向所有空格添加反斜杠:
此时,
SEARCH
包含te*/my\ files/more
.然后,使用
eval
.就这么简单!使用绕过来自变量
eval
的解释。${SEARCH}