unix - 使用 -iwholename 查找名称中带有括号的文件

标签 unix escaping find string-matching

我正在尝试查找可能包含[方括号]等可怕字符的任意文件。由于我使用的是 -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/

相关文章:

linux - SIGABRT 处理程序。在崩溃前做一些清理

c - 为什么我的程序的常驻集大小 (RSS) 大于可执行文件?

bash - UNIX 中的按键记录

shell - Unix : saving a sed command in a variable, 回显它,然后执行它

android - 你如何在 Android 中执行退格转义字符?

regex - 如何在 Haskell 的 Text.Regex 库中转义字符?

javascript - jquery .find 获取 <li> 中的文本

unix - 如何在unix中查找最近一小时内创建的文件

python - 为什么 python2 显示\r(原始转义)而 python3 不显示?

python - 查找不等于特定值的第一个元素的索引