Warum gibt dir *. * Mir alle Dateien und Ordner?

62

Wenn ich dir *.*es starte, entstehen unerwartete Ergebnisse. Sogar Dateien und Ordner ohne Punkt im Namen werden aufgelistet. Zum Beispiel

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

Warum ist das so? Gibt es eine Möglichkeit, nur Dateien mit einem Punkt aufzulisten?

phuclv
quelle
19
Der Punkt ist immer da, er wird nur gedruckt, wenn ihm etwas folgt. Mit anderen Worten, Sie denken vielleicht, eine Datei heißt "das ist meine Datei", aber im Geheimen lautet der Name "das ist meine Datei". mit nichts nach dem Punkt. Analog könnte man denken, dass der DNS-Name für diese Site "superuser.com" ist, aber tatsächlich "superuser.com". mit nichts nach dem zweiten Punkt.
Todd Wilcox
12
@ToddWilcox ist nur unter DOS korrekt. Moderne Dateisysteme in Windows haben keinen separaten Namensraum für Erweiterungen mehr
phuclv
13
@ LưuVĩnhPhúc Das Win32-Subsystem behandelt Dateinamen, die kein .ähnliches enthalten, .für viele Zwecke, einschließlich dieses.
CodesInChaos
2
Ordner, die das .Zeichen nicht enthalten , haben .am Ende ein implizites Zeichen. - Sie können beispielsweise einen Ordner mit dem Namen "Blah.old" haben, der dann eine herkömmliche Dateierweiterung mit drei Buchstaben hat. Für den täglichen Gebrauch ist " Blah" jedoch dasselbe wie " Blah.", egal ob es sich um eine Datei oder einen Ordner handelt.
BrainSlugs83
9
@ can-ned_food Todd Wilcox ist über DNS korrekt. Die Root-DNS-Zone wird wörtlich als bezeichnet ., und die Bezeichnungen in DNS-Namen werden durch getrennt .(daher ist der Name der Root-DNS-Zone eine einzelne Bezeichnung mit der Länge Null). Ein Kind der Stamm-DNS-Zone .ist com.und ein Kind von com.ist superuser.com.und so weiter.
ein CVn

Antworten:

115

Ich schreibe diese Antwort, weil OP Folgendes betont hat:

Was mich interessiert ist, warum *.*alle Dateien übereinstimmen, wie in der Frage angegeben

Der DIRBefehl stammt aus einer Zeit, in der:

  1. Punkt (.) War als Zeichen in Datei- oder Ordnernamen nicht zulässig
  2. Datei- und Ordnernamen waren auf 8 Zeichen für Namen und 3 Zeichen für Erweiterungen beschränkt

Nach diesem Standard *.*bedeutete dies daher, egal wie der Name und welche Erweiterung auch immer war . Dabei handelt es sich nicht um eine Zeichenfolge mit einem ".", Die Zeichen vor oder nach dem "." Enthalten kann oder nicht. .

Microsoft-Richtlinien gewährleisten die Abwärtskompatibilität. Daher wird diese Auslegung *.*beibehalten.

In Windows PowerShell *.*bedeutet dies jedoch eine Zeichenfolge mit einem ".", Die möglicherweise Zeichen vor oder nach dem "." .

jpaugh
quelle
25
Das ursprüngliche Dateisystem hat nicht einmal den Punkt selbst auf der Festplatte gespeichert, sondern nur die 11 Zeichen, die den Rest des Namens ausmachen.
Mr Lister
7
Es ist erwähnenswert, dass Dateien und Ordner ohne Dateierweiterungen weiterhin als leere Dateierweiterungen behandelt werden . Aus diesem Grund werden ein Ordner mit dem Namen " Folder." und ein Ordner mit dem Namen " Folder" für Windows gleich benannt.
BrainSlugs83
2
@MrLister Interessant. Wie haben die alten FS-Speichernamen AA.BBmit <8 im ersten Teil und <3 in der Erweiterung ausgesehen? Hat es nur mit Leerzeichen aufgefüllt?
Kelvin
3
@ Kelvin ja die beiden teile waren getrennt raumgepolstert.
Plugwash
12

Warum ist das so?

Man könnte eine Antwort auf " Warum ist das so? " Im Wildcards- Artikel finden:

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)

Regeln für den Wildcard-Abgleich

  • *Stimmt im Allgemeinen mit 0 oder mehr Zeichen überein, mit einer Ausnahme (siehe nächste Regel). Es steht dem nicht-gierigen Platzhalter frei, so viele oder so wenige Zeichen zuzuordnen, wie für den Rest der Maske erforderlich sind.

  • *.Am Ende der Maske werden 0 oder mehr Zeichen mit Ausnahme von {dot} gefunden. Tatsächlich gilt die Regel für eine beliebige Anzahl von {Punkt} und {Leerzeichen} zwischen dem * und dem Terminal {Punkt}. Der reguläre Ausdruck für diesen Begriff lautet"[*][. ]*[.]$"

  • ?Stimmt mit 0 oder einem Zeichen überein, außer mit {dot}. Die einzige Übereinstimmung mit 0 Zeichen besteht darin, dass das Ende des Namens oder die Position vor einem {Punkt} angegeben wird. Das Fragezeichen kann auch mehrmals verwendet werden, um mehr als ein Zeichen zu finden.

Implikation . Der letzte {Punkt} in einem Datei- / Ordnernamen trennt den Basisnamen und die Erweiterung. Damit

  • dir *.zeigt alle Einzelteile mit keiner Erweiterung und
  • dir *.*Zeigt alle Elemente mit einer Erweiterung von null oder mehr Zeichen an .

Streng genommen dir *.werden alle Elemente ohne Punkt ( .) im Namen angezeigt . (Übrigens, Benennen von Dateien, Pfaden und Namespaces MSDN-Artikel besagt ausdrücklich, dass " es akzeptabel ist, einen Punkt als erstes Zeichen eines Namens anzugeben ".)

Gibt es eine Möglichkeit, nur Dateien mit einem Punkt aufzulisten?

Ich glaube nicht Es gibt jedoch eine Problemumgehung mit einem passenden regulären Ausdruck.

PowerShell (Komplettlösung bei Verwendung in einer Powershell-Konsole):

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

Cmd (nur eine Idee, könnte etwas Ausarbeitung erfordern):

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

Nachtrag: Bonus und Erklärung

Eine intuitive Vermutung, Namedie verkettet ist BaseNameund Extension nicht gilt . Das folgende Skript beweist die Verwendung cmdund die PowerShellKernfunktionen, und der seltsame ^..*\...*$ reguläre Ausdruck wird aus den Ergebnissen abgeleitet.

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

Ausgabe :

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

Vergleichen Sie die Definition der BaseNameEigenschaft, die für Dateien und Ordner unterschiedlich ist:

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

Meine ursprüngliche Antwort basierte auf einem unverzeihlichen Missverständnis:

Lesen Sie dir /?, verwenden Sie 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

Ein anderer Ansatz: findstrRegex anwenden alsdir *.* | findstr /V "<.*>"

JosefZ
quelle
was mich interessiert ist, warum *.*alle
dateien
Ich fürchte , Ihr Alternativvorschlag (findstr) keine Ordner finden , die mit einem Start .wie .dbus-keyrings, .VirtualBoxund .vscode.
22
So dir /A:-Dlistet nur Dateien, die glücklich sind?
Quentin
4
"Gibt es eine Möglichkeit, nur Dateien mit einem Punkt aufzulisten?" dir /A:-Dist falsch. 1 / es listet Dateien ohne Endung auf. 2 / Es werden keine Verzeichnisse .
aufgelistet,
3
omg ... es ist Jahrzehnte her, seit ich "@echo off" das letzte Mal gesehen habe
am
7

Gibt es eine Möglichkeit, nur Dateien mit einem Punkt aufzulisten?

Sie können Dateinamen mit einem Punkt abgleichen <, indem Sie den undokumentierten Platzhalter verwenden , der entweder einer Folge von 0 oder mehr Zeichen im Basisnamen oder einer Folge von 0 oder mehr Zeichen in der Erweiterung entspricht:

dir "<.<"

Denken <Sie daran, dass dies auch ein Metazeichen ist. Sie müssen es daher immer dann zitieren oder maskieren, wenn Sie es in einem Muster aus der Befehlsshell verwenden.

Feersum
quelle
1
Ausgezeichnet. Diese undokumentierte Wildcard existiert tatsächlich
phuclv
1

Der Befehlszeileninterpreter sieht " . " Als "Alle Basisdateinamen" mit "Alle Erweiterungen". Eine leere Erweiterung ist immer noch eine Erweiterung , daher wird sie mit der Liste abgeglichen und zurückgegeben. Wie andere erklärt haben, ist dies ein Kater aus früheren Versionen von Windows und MS-DOS.

Wenn Sie gerne mit PowerShell suchen, ist das Auffinden dieser Dateien viel einfacher. Beachten Sie, dass "dir" in PowerShell ein Alias ​​für das Cmdlet "Get-ChildItem" ist.

So finden Sie alle Dateien (keine Verzeichnisse / Ordner) mit einer Erweiterung (z. B. "myfile.txt", aber nicht "FileWithNoExt"):

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

Der Schalter "-af" ist eine Abkürzung für "-File", wodurch die Rückgabeobjekte nur auf Dateien beschränkt werden. "-ad" würde nur Verzeichnisse erhalten. Das "\." bedeutet "ein buchstäbliches Punktzeichen". Ohne den umgekehrten Schrägstrich würde der Punkt mit jedem Zeichen übereinstimmen, wie es der reguläre reguläre Ausdruck vorsieht.

So rufen Sie alle Dateien ab, in denen der Name einen Punkt ohne die Erweiterung sowie eine Erweiterung enthielt (z. B. "myDocument_v1.1.doc", aber nicht "myfile.txt"):

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

Beachten Sie jedoch, dass dies eine Datei mit dem Namen ".archive" mit einem vorangestellten Punkt ausschließt. Dies liegt daran, dass es so behandelt wird, als hätte es keinen Basisnamen und die Erweiterung "archive". Wenn Sie diese einbeziehen möchten:

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

Hier lautet das Übereinstimmungsmuster "Ein Literalpunkt, OR (|) BeginningOfString (^) gefolgt von EndOfString ($) (dh eine leere Zeichenfolge)". Da eine Datei nicht gleichzeitig einen leeren Basisnamen und eine leere Erweiterung haben kann, werden die Dateien mit einem Punkt beginnend gefunden.

Dave_J
quelle
in PowerShell ist gerade ls *.*genug, wie viele andere vor Ihnen geantwortet haben
phuclv
-2

Wenn Sie obigen Befehl eingeben, dann hier: * (dies ist eine Wild Card , das jede Folge von Zeichen bedeutet) gefolgt von einem Punkt , gefolgt von * könnte dies alle Dateien als Show interpretiert werden , die Namen haben wie (.) (Jede Folge von Zeichen ). (eine beliebige Folge von Zeichen), was außerdem bedeutet, dass alle Dateien mit einer beliebigen Erweiterung angezeigt werden.

Rahul Kant
quelle
1
Warum ist dann Program Filesin der Liste enthalten? Es passt nicht zum Muster <sequence of characters>.<sequence of characters>.
Gronostaj
Stellen Sie es sich mehr als <Folge von null oder mehr Zeichen> vor. Aus diesem Grund wird auch eine Datei mit dem Namen ".info" abgerufen, deren Basisname leer ist.
Dave_J