【问题标题】:Gnuwin32 find.exe expands wildcard before performing search [closed]Gnuwin32 find.exe 在执行搜索之前扩展通配符[关闭]
【发布时间】:2011-04-29 01:43:42
【问题描述】:

我在 Windows 环境中使用 Gnuwin32 二进制文件。
当我想查找某种类型的文件时,比如说 PDF,我通常会运行:

find . -iname '*.pdf' -print

这在任何 UNIX 系统上都能完美运行。

find.exe . -iname "*.pdf" -print

但是在Windows下,用双引号代替了单引号,只有在当前目录中没有pdf文件的情况下才有效,否则*会被扩展

更糟糕的是:当当前目录中只有一个PDF文件时,它会展开,不会出现语法错误,并且会得到错误的结果。

我尝试使用插入符号、反斜杠、星号本身转义 *,并在双引号内添加:对我没有任何作用。

实例:

好的,这是我所有的文件:

C:\tmp>find . -type f
./a/1.pdf
./a/2.pdf
./a/aa/1.pdf
./b/1.pdf
./b/bb/1.pdf
./b/bb/2.pdf

良好的行为,未扩展通配符

C:\tmp>find . -iname "*.pdf"
./a/1.pdf
./a/2.pdf
./a/aa/1.pdf
./b/1.pdf
./b/bb/1.pdf
./b/bb/2.pdf

C:\tmp>cd a

注意,行为不一致,通配符已扩展:

C:\tmp\a>find . -iname "*.pdf"
find: paths must precede expression
Usage: find [-H] [-L] [-P] [path...] [expression]

C:tmp\a>cd ..\b

注意,行为不一致,通配符已扩展:

C:\tmp\b>find . -iname "*.pdf"
./1.pdf
./bb/1.pdf

谢谢

【问题讨论】:

  • 我不明白你想要什么。为什么不希望 * 扩展?如果不是,您认为 find 如何向您显示结果?
  • 因为我希望 find 的 argv[3] 等于 {'*','.','p','d','f'}。 Find 已经足够成熟,可以解读小丑了。
  • 例子:我有./a.pdf, ./b/a.pdf, ./b/b.pdf;我运行find . -iname "*.pdf"。 Cmd 将其扩展为find . -iname a.pdf,最终我的结果中没有得到./b/b.pdf。当然,使用 Unix shell,find . -iname '*.pdf' 可以获取所有 pdf 文件。
  • 在您的问题中显示您的批处理代码以更好地了解您的情况
  • 我运行find . -iname "*.pdf" 并且没有问题。它会显示我所有的 pdf 文件...

标签: find expansion gnuwin32


【解决方案1】:

我找到了解决问题的方法。

  • Gnuwin32 的find.exe 不适用于最近的Windows 版本(Vista、7),因为它扩展了仅匹配当前目录内容的通配符。
  • 同样,来自 UnxUtils 的旧版本 find.exe 也遇到了同样的错误。
  • The latest find.exe from UnxUtils 正在工作。

【讨论】:

  • 我自己被这个抓住了,并用答案回答了另一个帖子 (stackoverflow.com/questions/33860141/…)。对于mingw,设置一个全局“int _CRT_glob = 0;”在与 main 或 Winmain 相同的源文件中。然后关闭通配。有经验的程序员第一次看到这种情况时会感到非常震惊!
【解决方案2】:

一种解决方法是添加通配符/扩展,Windows shell 不会扩展,但 GNU find 会:

find.exe . -name *[.:]pdf -print

Windows shell[*] 不解释/扩展方括号。此外,冒号在 Windows 文件名中不是有效字符,因此此模式无法匹配任何 Windows 文件名,并且 Windows shell 将始终将该模式传递给 find.exe。

Find.exe 然后会查找任何以.pdf:pdf 结尾的文件,但由于在Windows 下没有文件可以具有以:pdf 结尾的名称,因此它只会查找以.pdf 结尾的文件。

[*] 实际上是 C 运行时执行/不执行这些通配符扩展。我对 Win32 C 运行时的理解不够好,无法细化区别,所以现在为了解决这个问题,我只是说“shell”。

【讨论】:

  • 小问题:执行扩展的是 C 运行时,而不是 shell。
【解决方案3】:

我今天下午遇到了这个问题。 Benoit 的 UnxUtils 可以工作。 我也发现 MinGW 的 find.exe 可以工作,它在我的

“MinGW\msys\1.0\bin”

目录。并且与手册一致。

gnuwin32 和 UnxUtils:find.exe . -name GameCli* 工作,但是 find.exe . -name 'GameCli*' 不起作用。

MinGW 的 find.exe . -name 'GameCli*' 工作。

【讨论】:

    【解决方案4】:

    我没有找到比避免通配符更好的方法

    find.exe . -iregex ".+\.pdf" -print
    

    【讨论】:

    • 注意:-iregex 不适用于某些版本的 gnuwin32 find.exe due to a bug
    【解决方案5】:

    @OP,我的行为始终如一

    C:\test\temp>find . -iname "*.txt"
    ./1.txt
    ./2.txt
    
    C:\test\temp>cd a
    
    C:\test\temp\a>find . -iname "*.txt"
    
    C:\test\temp\a>cd ..\b
    
    C:\test\temp\b>find . -iname "*.txt"
    
    C:\test\temp\b>find --version
    GNU find version 4.2.20
    Features enabled: CACHE_IDS D_TYPE
    

    您可能想尝试使用 findutils 而不是 UnxUtils。

    【讨论】:

    • 相同。当我使用C:\gnuwin32\bin\echo.exe "*.txt" 时,它会输出a.txt b.txt。也许是 cmd.exe 设置?
    • ghostdog74:你this message。您使用的是哪个版本的 Windows?
    • 我找到了解决问题的方法,感谢您帮助我诊断。实际上,它不是来自 cmd.exe,它从不扩展 * 并让程序自己做,而是来自 find.exe,它在最新版本的 Windows 上表现不同。
    猜你喜欢
    • 1970-01-01
    • 2022-01-11
    • 2019-01-04
    • 2022-11-03
    • 2021-10-29
    • 1970-01-01
    • 2011-08-10
    • 1970-01-01
    相关资源
    最近更新 更多