Pad*_*dau 12 scripts find wildcards
我想用来find在一组受通配符限制的文件夹中查找文件,但路径名中有空格。
从命令行,这很容易。以下示例均有效。
find te*/my\ files/more -print
find te*/'my files'/more -print
find te*/my' 'files/more -print
Run Code Online (Sandbox Code Playgroud)
例如,这些将在terminal/my files/more和 中找到文件tepid/my files/more。
但是,我需要将其作为脚本的一部分;我需要的是这样的:
SEARCH='te*/my\ files/more'
find ${SEARCH} -print
Run Code Online (Sandbox Code Playgroud)
不幸的是,无论我做什么,我似乎都无法find在脚本中的命令中混合使用通配符和空格。上面的示例返回以下错误(注意反斜杠的意外加倍):
find: ‘te*/my\\’: No such file or directory
find: ‘files/more’: No such file or directory
Run Code Online (Sandbox Code Playgroud)
尝试使用引号也会失败。
SEARCH="te*/'my files'/more"
find ${SEARCH} -print
Run Code Online (Sandbox Code Playgroud)
这将返回以下错误,忽略引号的含义:
find: ‘te*/'my’: No such file or directory
find: ‘files'/more’: No such file or directory
Run Code Online (Sandbox Code Playgroud)
这里再举一个例子。
SEARCH='te*/my files/more'
find ${SEARCH} -print
Run Code Online (Sandbox Code Playgroud)
正如预期的那样:
find: ‘te*/my’: No such file or directory
find: ‘files/more’: No such file or directory
Run Code Online (Sandbox Code Playgroud)
我尝试过的每个变体都会返回一个错误。
我有一个解决方法,它有潜在危险,因为它返回太多文件夹。我将所有空格转换为问号(单字符通配符),如下所示:
SEARCH='te*/my files/more'
SEARCH=${SEARCH// /?} # Convert every space to a question mark.
find ${SEARCH} -print
Run Code Online (Sandbox Code Playgroud)
这相当于:
find te*/my?files/more -print
Run Code Online (Sandbox Code Playgroud)
这不仅会返回正确的文件夹,还会返回terse/myxfiles/more不应该的 .
我怎样才能实现我想要做的事情?谷歌没有帮助我:(
ter*_*don 10
完全相同的命令在脚本中应该可以正常工作:
#!/usr/bin/env bash
find te*/my\ files/ -print
Run Code Online (Sandbox Code Playgroud)
如果你需要把它作为一个变量,它会变得更复杂一些:
#!/usr/bin/env bash
search='te*/my\ files/'
eval find "$search" -print
Run Code Online (Sandbox Code Playgroud)
那样使用eval是不安全的,如果您的文件名可以包含某些字符,则可能会导致执行任意且可能有害的代码。有关详细信息,请参阅bash 常见问题 48。
最好将路径作为参数传递:
#!/usr/bin/env bash
find "$@" -name "file*"
Run Code Online (Sandbox Code Playgroud)
另一种方法是find完全避免并使用 bash 的扩展通配功能和通配符:
#!/usr/bin/env bash
shopt -s globstar
for file in te*/my\ files/**; do echo "$file"; done
Run Code Online (Sandbox Code Playgroud)
在globstarbash的选项,您可以使用**递归匹配:
globstar
If set, the pattern ** used in a pathname expansion con?
text will match all files and zero or more directories
and subdirectories. If the pattern is followed by a /,
only directories and subdirectories match.
Run Code Online (Sandbox Code Playgroud)
要使其 100% 像查找和包含点文件(隐藏文件)一样,请使用
#!/usr/bin/env bash
shopt -s globstar
shopt -s dotglob
for file in te*/my\ files/**; do echo "$file"; done
Run Code Online (Sandbox Code Playgroud)
您甚至echo可以在没有循环的情况下直接使用它们:
echo te*/my\ files/**
Run Code Online (Sandbox Code Playgroud)