为什么`dir *.*` 给我所有文件和文件夹?

phu*_*clv 63 windows command-line dir filenames directory-listing

当我运行dir *.*它时会产生意想不到的结果。甚至列出名称中没有任何点的文件和文件夹。例如

C:\>dir *.*
 Volume in drive C is System
 Volume Serial Number is AC0A-29DA

 Directory of C:\

14-03-2017  05:17 PM             8,192 ntuser.dat
03-01-2017  07:10 PM    <DIR>          Perl520
28-03-2017  10:13 AM    <DIR>          Program Files
28-03-2017  10:13 AM    <DIR>          Program Files (x86)
04-01-2017  03:25 PM    <JUNCTION>     Python27 [C:\Program Files\Anaconda]
06-02-2017  10:16 PM    <DIR>          SAP
28-03-2017  04:10 PM               152 useragent.log
03-01-2017  03:04 PM    <DIR>          Users
16-03-2017  04:24 PM    <DIR>          VM
22-03-2017  11:13 AM    <DIR>          Windows
               2 File(s)          8,344 bytes
               8 Dir(s)  270,172,966,912 bytes free
Run Code Online (Sandbox Code Playgroud)

这是为什么?有没有办法只列出带点的文件?

小智 115

我写这个答案是因为 OP 强调:

我感兴趣的是为什么*.*匹配所有文件,如问题中所述

DIR命令来自以下时间:

  1. 句点 (.) 不允许作为文件或文件夹名称中的字符
  2. 文件和文件夹名称的名称限制为 8 个字符,扩展名限制为 3 个字符

因此,通过这一标准,*.*意味着无论名称和任何扩展。它并不意味着 包含“.”的字符串,该字符串在“.”之前或之后可能有也可能没有字符。.

Microsoft 策略是保留向后兼容性。因此,*.*保留了对 的解释。

但在 Windows PowerShell 中,*.*表示包含“.”的字符串,在“.”之前或之后可能有也可能没有字符。.

  • 原始文件系统甚至没有将句点本身存储在磁盘上,只有 11 个字符组成了名称的其余部分。 (25认同)
  • 补充阅读:https://blogs.msdn.microsoft.com/oldnewthing/20071217-00/?p=24143 (10认同)
  • 值得注意的是,没有扩展名的文件和文件夹仍被视为具有**空白扩展名**。因此,就 Windows 而言,名为“`Folder.`”的文件夹和名为“`Folder`”的文件夹命名相同。 (8认同)
  • @Kelvin 是的,这两个部分是单独用空格填充的。 (3认同)
  • @MrLister 有趣。旧的 FS 如何存储像 `AA.BB` 这样第一部分 &lt; 8 和扩展名 &lt; 3 的文件名?它只是用空格填充吗? (2认同)
  • @BrainSlugs83 不是这样。https://i.imgur.com/710MUG7.png (2认同)
  • @DavidPostill 但请参阅:http://imgur.com/Ug​​mX8xi 它们对于某些目的是相同的,而对于其他目的则不同。 (2认同)

Jos*_*efZ 12

这是为什么?

人们可以在通配符文章中找到“为什么会这样? ”的答案:

The * wildcard will match any sequence of characters
               (0 or more, including NULL characters)

The ? wildcard will match a single character
               (or a NULL at the end of a filename)
Run Code Online (Sandbox Code Playgroud)

通配符匹配规则

  • *通常匹配任何 0 个或多个字符,但有一个例外(请参阅下一条规则)。非贪婪通配符可以自由匹配掩码其余部分所需的尽可能多或尽可能少的字符。

  • *.在掩码末尾匹配除 {dot} 之外的任何 0 个或多个字符。实际上,该规则适用于 * 和终端 {dot} 之间的任意数量的 {dot} 和 {space} 字符。这个词的正则表达式是"[*][. ]*[.]$"

  • ?匹配 0 或 1 个字符,{dot} 除外。它匹配 0 个字符的唯一时间是匹配名称的结尾或 {dot} 之前的位置。问号也可以多次使用以匹配多个字符。

言外之意。文件/文件夹名称中的最后一个{dot}分隔基本名称和扩展名。所以

  • dir *.显示所有没有扩展名的项目,以及
  • dir *.*显示扩展名为零个或多个字符的所有项目

严格来说,dir *.显示name 中没有句点( ) 的所有项目.。(顺便说一句,命名文件、路径和命名空间MSDN 文章明确指出“将句点指定为名称的第一个字符是可以接受的”。)

有没有办法只列出带点的文件?

我不这么认为。但是,有一个合适的正则表达式的解决方法。

PowerShell(全范围解决方案,如果在 Powershell 控制台中使用):

:: PowerShell - no extension, full syntax
PowerShell -c "Get-ChildItem | Where-Object {$_.Name -match '^.[^\.]*$'}"
:: PowerShell -    extension, alias syntax
PowerShell -c "dir | ? {$_.Name -match '^..*\...*$'}"
Run Code Online (Sandbox Code Playgroud)

Cmd(只是一个想法,可能需要一些详细说明):

:: CMD/batch - no extension
for /F "delims=" %%G in ('dir /OGN /B ^| findstr "^.[^\.]*$"') do @echo %%~tG %%~aG %%~zG %%~nxG
:: CMD/batch -    extension
for /F "delims=" %%G in ('dir /OGN /B ^| findstr "^..*\...*$"') do @echo %%~tG %%~aG %%~zG %%~nxG
Run Code Online (Sandbox Code Playgroud)

附录:奖金和解释

一个直观的猜测,它Name被连接起来BaseName并且Extension 不成立。以下脚本使用cmdPowerShell核心功能证明了它,奇怪的 ^..*\...*$正则表达式来自它的结果。

@ECHO OFF
SETLOCAL EnableExtensions DisableDelayedExpansion
set "_workingDirectory=%~1"
if "%_workingDirectory%"=="%tmp%\tests_SU_1193102" (
  >NUL 2>&1 (
      mkdir "%_workingDirectory%"
      pushd "%_workingDirectory%"
      rem make directories
      mkdir     .Fldr-Ext
      mkdir     aFldr-Ext
      mkdir     .Fldr.Ext
      mkdir     aFldr.Ext
      rem create files
      copy  NUL .File-Ext 
      copy  NUL aFile-Ext 
      copy  NUL .File.Ext 
      copy  NUL aFile.Ext
      popd
  )
) else if "%_workingDirectory%"=="" set "_workingDirectory=%CD%"
pushd "%_workingDirectory%"
set "_first=ItemName  Attributes    BaseName Extension"
echo ON
::                        dir /OGN | findstr "Ext$"
for /F "delims=" %%G in ('dir /OGN /B') do @((if defined _first (echo %_first%&echo(&set "_first="))&echo %%~nxG %%~aG  %%~nG   %%~xG)
::   Get-ChildItem | Select-Object -Property Mode, BaseName, Extension, Name
PowerShell -c "dir | select -pr Name, Mode, BaseName, Extension | sort -pr @{Expression='Mode';Descending=$true}, @{Expression='Name';Descending=$false}"
Run Code Online (Sandbox Code Playgroud)

输出

==> D:\bat\BaseName_vs_Extension.bat "%tmp%\tests_SU_1193102"

==> for /F "delims=" %G in ('dir /OGN /B') do @((if defined _first (echo ItemName  Attributes   BaseName Extension  & echo(  & set "_first=" ) )  & echo %~nxG %~aG     %~nG    %~xG )
ItemName  Attributes    BaseName Extension

.Fldr.Ext d----------   .Fldr   .Ext
.Fldr-Ext d----------           .Fldr-Ext
aFldr.Ext d----------   aFldr   .Ext
aFldr-Ext d----------   aFldr-Ext
.File.Ext --a--------   .File   .Ext
.File-Ext --a--------           .File-Ext
aFile.Ext --a--------   aFile   .Ext
aFile-Ext --a--------   aFile-Ext

==> PowerShell -c "dir | select -pr Name, Mode, BaseName, Extension | sort -pr @{Expression='Mode';Descending=$true}, @{Expression='Name';Descending=$false}"

Name      Mode   BaseName  Extension
----      ----   --------  ---------
.Fldr.Ext d----- .Fldr.Ext .Ext
.Fldr-Ext d----- .Fldr-Ext .Fldr-Ext
aFldr.Ext d----- aFldr.Ext .Ext
aFldr-Ext d----- aFldr-Ext
.File.Ext -a---- .File     .Ext
.File-Ext -a----           .File-Ext
aFile.Ext -a---- aFile     .Ext
aFile-Ext -a---- aFile-Ext
Run Code Online (Sandbox Code Playgroud)

比较BaseName属性定义,文件和文件夹不同:

PS D:\PShell> Get-ChildItem | Get-Member -Name BaseName | Format-List -property TypeName, Definition


TypeName   : System.IO.DirectoryInfo
Definition : System.Object BaseName {get=$this.Name;}

TypeName   : System.IO.FileInfo
Definition : System.Object BaseName {get=if ($this.Extension.Length -gt 
             0){$this.Name.Remove($this.Name.Length - 
             $this.Extension.Length)}else{$this.Name};}
Run Code Online (Sandbox Code Playgroud)

最初的回答是基于不可原谅的误解:

阅读dir /?,使用dir /A:-D

/A          Displays files with specified attributes.
attributes   D  Directories                R  Read-only files
             H  Hidden files               A  Files ready for archiving
             S  System files               I  Not content indexed files
             L  Reparse Points             -  Prefix meaning not
Run Code Online (Sandbox Code Playgroud)

另一种方法:将findstr正则表达式应用为dir *.* | findstr /V "<.*>"

  • 那么`dir /A:-D` 只列出满意的文件吗? (23认同)
  • “有没有办法只列出带点的文件?” `dir /A:-D` 不正确。1/ 它列出没有扩展名的文件。2/ 它没有列出名称中带有 `.` 的目录(完全合法) (4认同)
  • 天啊……我上次看到“@echo off”已经有几十年了 (3认同)

小智 6

有没有办法只列出带点的文件?

您可以使用未记录的通配符将文件名与点<匹配,该通配符匹配基本名称中的 0 个或多个字符序列或扩展名中的 0 个或多个字符序列:

dir "<.<"
Run Code Online (Sandbox Code Playgroud)

请记住,这<也是一个元字符,因此无论何时在命令 shell 的模式中使用它时都需要引用或转义它。

  • 出色的。这个[未记录的通配符](https://ss64.com/nt/syntax-wildcards.html)确实存在 (2认同)