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


62

当我运行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

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


19
点总是存在的,除非它后面没有东西,否则它不会被打印。换句话说,您可能会认为文件名为“这是我的文件”,但是秘密地名称是“这是我的文件”。点后没有任何东西。类似地,您可能会认为该站点的DNS名称是“ superuser.com”,但实际上是“ superuser.com”。第二个点之后没有任何内容。
Todd Wilcox

12
@ToddWilcox它仅在DOS中正确。Windows中的现代文件系统不再具有单独的扩展名称空间
phuclv

13
@不包含LưuVĩnhPhúcWin32子系统对待文件名.,如他们有一个.最终的多种用途,包括这一个。
CodesInChaos

2
不包含该.字符的文件夹.的末尾有一个隐含字符。-您可以有一个名为“ Blah.old”的文件夹,然后它将具有传统的3字母扩展名;不管是文件还是文件夹,“ Blah”都与“ Blah.” 相同,但仍可用于日常使用。
BrainSlugs83

9
@ can-ned_food Todd Wilcox关于DNS是正确的。根DNS区域在字面上称为.,并且DNS名称中的标签由分隔.(因此,根DNS区域的名称是单个零长度标签)。根DNS区域的一个子.com.,和一个孩子com.superuser.com.,等等。
CVn

Answers:


115

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

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

DIR命令来自以下时间:

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

因此,按照该标准,*.*意味着无论其名称和扩展名。它并不表示 包含“。”的字符串,该字符串可能在“。”之前或之后都没有字符。

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

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



25
原始文件系统甚至没有将句点本身存储在磁盘上,只有11个字符组成了名称的其余部分。
李斯特先生,2017年

7
值得注意的是,没有扩展名的文件和文件夹仍被视为具有空白扩展名。因此,就Windows而言,Folder.名为“ Folder” 的文件夹和名为“ ”的文件夹的名称相同。
BrainSlugs83

2
@MrLister有趣。旧的FS如何存储文件名,例如AA.BB第一部分<8,扩展名<3。它只是填充空格吗?
Kelvin

3
@Kelvin是的,这两个部分分别用空格填充。
–plugwash

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)

通配符匹配规则

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

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

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

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

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

严格来说,在name中dir *.显示所有不带句号.)的项目。(BTW,命名文件,路径和命名空间 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 '^..*\...*$'}"

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

附录:奖金和解释

直觉的猜测Name是串联的BaseNameExtension 不成立。下面的脚本通过使用cmdPowerShell核心功能对其进行了证明,而奇怪的 ^..*\...*$ regex是从其结果中得出的。

@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}"

输出

==> 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

比较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};}

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

阅读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

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


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

恐怕您的替代建议(FINDSTR)没有找到以a开头的文件夹.一样.dbus-keyrings.VirtualBox.vscode

22
因此,dir /A:-D仅列出满意的文件?
昆汀

4
“有没有办法只列出带点的文件?” dir /A:-D是不正确的。1 /它列出了没有扩展名的文件。2 /它未列出.名称中具有的目录(完全合法)
DavidPostill

3
omg ...距离我上次看到“ @echo off”已有数十年了
rupps

7

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

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

dir "<.<"

请记住,这<也是一个元字符,因此,在命令外壳中以某种模式使用它时,都需要引用或转义它。


1
优秀的。此未记录的通配符确实存在
phuclv

1

命令行解释器会将“ ”显示为带有“所有扩展名”的“所有基本文件名”。空白扩展名仍然是extension,因此将与列表匹配并返回。正如其他人所解释的,这是Windows和MS-DOS的早期版本的宿醉。

如果您愿意使用PowerShell,则查找这些文件要容易得多。请注意,在PowerShell中,“ dir”是“ Get-ChildItem” cmdlet的别名。

要查找具有扩展名(例如“ myfile.txt”但不是“ FileWithNoExt”)的所有文件(不是目录/文件夹):

dir -af | Where {$_.Name -match "\."}

“ -af”开关是“ -File”的简写,它将返回对象限制为仅文件。“ -ad”将仅获取目录。“ \”。表示“文字点字符”。如果没有反斜杠,则根据标准正则表达式,点将匹配任何字符。

要获取名称中带有点的,不带扩展名的所有文件以及扩展名(例如,“ myDocument_v1.1.doc”而不是“ myfile.txt”):

dir -af | Where {$_.BaseName -match "\."}

但是请注意,这将排除名称如“ .archive”的文件,且文件名前带有点。这是因为它被视为没有基本名称,并且没有“ archive”的扩展名。如果要包括这些:

dir -af | Where {$_.BaseName -match "\.|^$"}

在此,匹配模式显示为“原义点,或(())BeginningOfString(^),后跟EndOfString($)(即空字符串)”。由于文件不能同时具有空的基名扩展名,因此它将找到以点开头的文件。


在PowerShell中就ls *.*足够了,正如许多其他人在您之前回答的那样
phuclv 18/09/28

-2

如果您键入上面的命令,则在这里:*(这是一个通配符,表示任何字符序列),后跟一个点号(。),后跟*,这可以解释为显示所有具有以下名称的文件(任何字符序列) )(任何字符序列),这还意味着显示所有具有任何扩展名的文件。


1
那为什么要Program Files列入清单呢?它与模式不匹配<sequence of characters>.<sequence of characters>
gronostaj

可以将其更多地视为<零个或多个字符的序列>这就是为什么它还会选择一个名为“ .info”的文件的原因,该文件的基本名称为空白。
Dave_J
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.