【问题标题】:Strange Windows DIR command behavior奇怪的 Windows DIR 命令行为
【发布时间】:2012-06-21 20:25:32
【问题描述】:

我在查找名称中带有数字的文件时偶然发现了这一点。当我输入时:

dir *号码*

(其中数字表示从 0 到 9 的任意数字,星号和数字之间没有空格)

在 cmd.exe 命令提示符下,它会返回各种文件中未出现的任何文件以符合搜索条件。奇怪的是,根据目录,一些数字会起作用,而其他数字则不起作用。例如,在与网站关联的目录中,我键入以下内容:

dir *4*

返回的是:

C:\Ampps\www\includes\pages 目录 2012 年 4 月 30 日下午 03:55 153 inventory_list_retrieve.php 2012 年 6 月 18 日上午 11:17 6,756 ix.html 2012 年 6 月 19 日下午 1:47 257,501 jquery.1.7.1.js 3 个文件 264,410 字节 0 Dir(s) 362,280,906,752 字节空闲

这对我来说没有任何意义。有什么线索吗?

这个问题是在 stackOverflow 上提出的,因为 DIR 命令在批处理程序中经常与 FOR 结合使用。如果使用 DIR 命令,奇怪的 DIR 行为似乎会使批处理程序可能不可靠。

编辑:(附加说明)。虽然已经过去了很长时间,但我发现了另一个怪癖,这几乎让我付出了很多工作。我想删除特定目录树中的所有 .htm 文件。就在这样做之前,我意识到*.htm 也与.html 文件匹配。此外,*.man 匹配 .manifest,可能还有其他匹配项。至少可以说,删除该特定目录中的所有 .html 文件会令人沮丧。

【问题讨论】:

  • 有趣!我们需要对这件事做一些测试......
  • 哇,这么多年过去了 - 仍然对这项技术感到惊讶。我可以确认这种奇怪的行为。
  • 虽然这个问题没有明确解决批处理编程,但潜在的问题对批处理编程有深远的影响。请不要以与编程无关的理由关闭此问题。
  • 如果有能力投票反对关闭投票,我会的。如果问题已关闭,我将投票重新开放。这是在命令提示符和批处理文件中都暴露的 Windows API 的一个潜在问题。恕我直言,这显然是批处理和 cmd 标签的主题。

标签: windows command-line batch-file cmd dir


【解决方案1】:

命令提示符下的通配符与长文件名和短“8.3”名称(如果存在)匹配。这可能会产生惊喜。

要查看短名称,请使用DIR 命令的/X 选项。

请注意,此行为并非特定于 DIR 命令,并且当通配符与任何命令(例如 DEL)的匹配次数超出预期时,可能会导致其他(通常是令人不快的)意外。

与 *nix shell 不同,用匹配名称列表替换文件模式是在每个命令中实现的,而不是由 shell 本身实现的。这可能意味着不同的命令可以实现不同的通配符模式规则,但实际上这种情况很少见,因为 Windows 提供 API 调用来搜索目录中与模式匹配的文件,并且大多数程序以明显的方式使用这些调用。对于使用“常用”工具以 C 或 C++ 编写的程序,该扩展由 C 运行时库使用 Windows API “免费”提供。

有问题的 Windows API 是 FindFirstFile() 及其近亲 FindFirstFileEx()FindNextFile()FindClose()

奇怪的是,尽管FindFirstFile() 的文档将其 lpFileName 参数描述为“目录或路径,并且文件名可以包含通配符,例如星号 (*) 或问号 (@987654337 @)" 它从未真正定义 *? 字符的含义。

文件模式的确切含义在 1970 年代早期的 CP/M 操作系统中已有历史,它强烈影响了 MSDOS 的设计(有些人可能会说“被直接复制”而不是“影响”)。这导致了许多“有趣的”工件和行为。从 2007 年开始,this blog post 描述了 DOS 端的其中一些内容,Raymond 准确地描述了文件模式是如何在 DOS 中实现的。

【讨论】:

    【解决方案2】:

    是的。如果您尝试以下操作,您会发现它还会搜索短名称:

    dir /x *4*
    

    (/x 开关用于短名称)

    过滤文件名使用:

    dir /b | find "4"
    

    【讨论】:

    • 如果您只想在长名称中进行搜索,请使用 |找到
    • +1,是的,“隐藏”的短文件名会导致不明显的问题。使用 FIND 的建议应该有效:dir /b | find "4"。使用 FINDSTR 将允许通过正则表达式进行更有选择性的过滤。
    【解决方案3】:

    引用RBerteig的回答:

    请注意,此行为并非特定于 DIR 命令, 并且当外卡出现时可能会导致其他(通常是不愉快的)惊喜 在任何命令(例如 DEL)上匹配的次数超出预期。

    即使对于非常讨厌的 FOR 命令,上述情况也是如此。

    for %A in (*4*) do @echo %A contains a 4
    

    还将搜索短名称。再次解决方案是使用 FIND 或 FINDSTR 以更可靠的方式过滤掉名称。

    for %A in (*) do @echo %A | >nul findstr 4 && echo %A contains a 4
    

    注意 - 如果在批处理文件中使用该命令,请将 %A 更改为 %%A。

    将 FOR 与 FINDSTR 结合使用是一种通用方法,可以安全地使用遇到短文件名问题的任何命令。只需将 ECHO 替换为问题命令,例如 COPY 或 DEL。

    【讨论】:

      【解决方案4】:

      似乎 dir 命令在后台搜索也很短(8.3 方式)文件名。

      当我打电话给dir *1* 时,我得到的是:

       Volume in drive C is System
       Volume Serial Number is F061-0B78
      
       Directory of C:\Users\Piotrek\Desktop\Downloads
      2012-05-20  17:33        23 639 040 gDEBugger-5_8.msi
      2012-05-20  17:30           761 942 glew-1.7.0.zip
      2012-05-20  17:11         9 330 176 irfanview_plugins_433_setup.exe
      2012-05-24  20:17         4 419 192 SumatraPDF-2.1.1-install.exe
      2012-05-15  22:55         3 466 248 TrueCrypt Setup 7.1a.exe
                     5 File(s)  1 127 302 494 bytes
      

      列出的文件中有一个gDEBugger-5_8.msi 文件,其中显然没有任何1 字符。

      当我将/X 开关与 dir 命令一起使用时,一切都变得清晰起来,这使得 dir 使用 8.3 文件名。 dir /X *1* 命令的输出:

       Volume in drive C is System
       Volume Serial Number is F061-0B78
      
       Directory of C:\Users\Piotrek\Desktop\Downloads
      
      
      2012-05-20  17:33        23 639 040 GDEBUG~1.MSI gDEBugger-5_8.msi
      2012-05-20  17:30           761 942 GLEW-1~1.ZIP glew-1.7.0.zip
      2012-05-20  17:11         9 330 176 IRFANV~1.EXE irfanview_plugins_433_setup.exe
      2012-05-24  20:17         4 419 192 SUMATR~1.EXE SumatraPDF-2.1.1-install.exe
      2012-05-15  22:55         3 466 248 TRUECR~1.EXE TrueCrypt Setup 7.1a.exe
                     5 File(s)  1 127 302 494 bytes
      

      引用来自 dir 的帮助:

      /X          This displays the short names generated for non-8dot3 file
                  names.  The format is that of /N with the short name inserted
                  before the long name. If no short name is present, blanks are
                  displayed in its place.
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-07-21
        • 2015-03-28
        • 1970-01-01
        • 2012-04-05
        • 1970-01-01
        • 2022-01-05
        • 2015-12-07
        • 2015-01-11
        相关资源
        最近更新 更多