我正在尝试查找可能包含[方括号]等可怕字符的任意文件。由于我使用的是 -iwholename
,我假设 find
按字面意思处理 -iwholename
参数,但以下仅在括号转义时才有效。
$ touch [aoeu]
$ ls
[aoeu]
$ find ./ -type f -iwholename ./[AOEU]
$ find ./ -type f -iwholename ./\\[AOEU\\]
./[aoeu]
我找到了this answer ,但它谈论的是正则表达式,我不想使用它。我只是做了更多尝试;我还意识到 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*
对于任意字符串,如何避免对某些字符进行非字面解释?为什么会发生这种情况?
编辑:
再次阅读 'effing 联机帮助页总是好的。这次我找到了之前错过的东西:
-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.
我的“为什么”问题得到了解答;现在,正如我之前所说,“对于任意字符串,如何避免对某些字符进行非字面解释?”
最佳答案
在 BSD 中的 man find
页面中,我看到:
-path pattern True if the pathname being examined matches pattern. Special shell pattern matching characters (``['', ``]'', ``*'', and ``?'') may be used as part of pattern. These characters may be matched explicitly by escaping them with a backslash (``\''). Slashes (``/'') are treated as normal characters and do not have to be matched explicitly.
(并且 -path
与 -wholename
相同,-iwholename
与 -path
相同但不区分大小写)
您必须转义这些字符,因为否则它们对 shell 具有特殊含义。这对于 -name
和 -iname
等其他标志是相同的。
要使您的 find
能够处理任意字符串,您需要转义这些特殊字符,例如如下所示:
escaped=$(sed -e 's/[][?*]/\\&/g' <<< "*aoeu*")
find ./ -iwholename "$escaped"
更新
正如您自己所发现的,如果您需要每秒替换大量模式,那么使用 bash
进行替换而不是生成 sed
会更有效code> 每次,就像这样:
filename_escaped="${filename//\[/\\[}"
filename_escaped="${filename_escaped//\]/\\]}"
filename_escaped="${filename_escaped//\*/\\*}"
filename_escaped="${filename_escaped//\?/\\?}"
关于unix - 使用 -iwholename 查找名称中带有括号的文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20892134/