我试图找到任意文件,其中可能包含其他可怕的字符,方括号。由于我使用的是-iwholename,所以我假设find按字面方式处理-iwholename参数,但是只有当括号被转义时,以下内容才能起作用。
$ touch [aoeu]
$ ls
[aoeu]
$ find ./ -type f -iwholename ./[AOEU]
$ find ./ -type f -iwholename ./\\[AOEU\\]
./[aoeu]我找到了this answer,但它说的是regexes,我不想使用它。我只是在做更多的实验;我还意识到find正在做一些我不希望做的事情:
$ touch \*aoeu\*
$ ls
[aoeu] *aoeu*
$ find ./ -type f -iwholename ./\*AOEU\* # I don't expect this expansion.
./*aoeu*
./[aoeu]
$ find ./ -type f -iwholename ./\\\*AOEU\\\*
./*aoeu*对于任意的字符串,如何避免某些字符的非文字解释?为什么会发生这种事?
编辑:
再读一遍“做爱手册”总是很好的。这次我发现了我以前错过的东西:
-iwholename pattern
Like -wholename, but the match is case insensitive.
-wholename pattern
See -path. This alternative is less portable than -path.
-path pattern
File name matches shell pattern pattern. The metacharacters do not treat `/' or `.' specially; so, for example,
find . -path "./sr*sc"
will print an entry for a directory called `./src/misc' (if one exists). To ignore a whole directory tree, use -prune rather than checking every file in the tree. For example, to skip the directory `src/emacs' and all files and directories under it, and print the names of the other files found, do something like this:
find . -path ./src/emacs -prune -o -print
Note that the pattern match test applies to the whole file name, starting from one of the start points named on the command line. It would only make sense to use an absolute path name here if the relevant start point is also an absolute path. This means that this command will never match anything:
find bar -path /foo/bar/myfile -print
The predicate -path is also supported by HP-UX find and will be in a forthcoming version of the POSIX standard.我的“为什么”问题得到了回答;现在,正如我前面所说的,“对于任意的字符串,我如何避免对某些字符进行非文字解释?”
发布于 2014-01-02 21:33:38
在我的man find页面中,我看到:
如果正在检查的路径名与模式匹配,则为-path模式。特殊的外壳模式匹配字符(
['',)‘’,\*'', and?‘’可以作为模式的一部分使用。这些字符可以通过用反斜杠(\''). Slashes (/'')显式转义来显式匹配,这些字符被视为普通字符,不必显式匹配。
( -path与-wholename相同,-iwholename与-path相同,但不区分大小写)
您必须转义这些字符,因为它们对shell有特殊的意义,否则。-name和-iname等其他标志也是如此。
要使您的find使用任意字符串,您需要转义这些特殊字符,例如:
escaped=$(sed -e 's/[][?*]/\\&/g' <<< "*aoeu*")
find ./ -iwholename "$escaped"更新
正如您自己发现的那样,如果您需要每秒替换许多模式,那么使用bash代替每次生成sed会更有效,如下所示:
filename_escaped="${filename//\[/\\[}"
filename_escaped="${filename_escaped//\]/\\]}"
filename_escaped="${filename_escaped//\*/\\*}"
filename_escaped="${filename_escaped//\?/\\?}"https://stackoverflow.com/questions/20892134
复制相似问题