62 votes

Pourquoi le "répertoire *.*" me donne tous les fichiers et dossiers ?

Quand je cours dir *.* cela produit des résultats inattendus. Même les fichiers et les dossiers dont le nom ne contient pas de point sont répertoriés. Par exemple

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

Pourquoi ça ? Existe-t-il un moyen de ne répertorier que les fichiers comportant un point ?

114voto

J'écris cette réponse parce que le PO l'a souligné :

ce qui m'intéresse, c'est pourquoi *.* correspond à tous les fichiers, comme indiqué dans la question

En DIR Le commandement vient d'une époque où :

  1. Le point (.) n'était pas autorisé comme caractère dans les noms de fichiers ou de dossiers
  2. Les noms de fichiers et de dossiers étaient limités à 8 caractères pour le nom et à 3 caractères pour les extensions.

Par conséquent, selon cette norme, *.* signifiait quel que soit le nom et quelle que soit l'extension . Il s'agit de ne voulait pas dire une chaîne contenant un ".", qui peut avoir ou non des caractères avant ou après le ".". .

La politique de Microsoft est de préserver la rétrocompatibilité. Par conséquent, cette interprétation de *.* est conservé.

Mais dans Windows PowerShell, *.* signifie une chaîne contenant un ".", qui peut avoir ou non des caractères avant ou après le ".". .

11voto

JosefZ Points 11907

Pourquoi ça ?

On pourrait trouver une réponse à " Pourquoi ça ? " dans Wildcards article :

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)

Règles de correspondance par caractères génériques

  • * Correspond généralement à 0 ou plusieurs caractères, à une exception près (voir la règle suivante). Le caractère générique non avide est libre de correspondre à autant de caractères ou plus que nécessaire. caractères que nécessaire pour que le reste du masque corresponde. corresponde.

  • *. À la fin du masque, la règle correspond à 0 caractère ou plus, à l'exception de {dot}. En réalité, la règle s'applique avec n'importe quel nombre de caractères {dot} et {espace} entre le * et le {point} terminal. L'expression régulière régulière pour ce terme est "[*][. ]*[.]$"

  • ? Correspond à 0 ou un caractère, sauf {dot}. La seule fois où elle correspond à 0 caractère est lorsqu'elle correspond à la fin du nom, ou à la position avant un {point}. Le point d'interrogation peut également être utilisé plusieurs fois une fois pour faire correspondre plus d'un caractère.

Implication . En dernier {dot} dans un nom de fichier/dossier sépare le nom de la base et l'extension. Ainsi,

  • dir *. affiche tous les articles avec aucune extension et
  • dir *.* affiche tous les articles avec extension de zéro ou plusieurs caractères .

A proprement parler, dir *. affiche tous les articles avec pas de période ( . ) en nom . (BTW, Nommer les fichiers, les chemins et les espaces de noms L'article de MSDN dit explicitement que " il est acceptable de spécifier un point comme premier caractère d'un nom ".)

Existe-t-il un moyen de ne lister que les fichiers avec un point ?

Je ne pense pas. Cependant, il existe une solution de contournement avec une expression régulière adaptée.

PowerShell (solution complète si elle est utilisée dans une console Powershell) :

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

Cmd (une idée seulement, qui pourrait nécessiter une certaine élaboration) :

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

Addendum : un bonus et une explication

Une supposition intuitive que Name est concaténée BaseName y Extension ne tient pas . Le script suivant le prouve à l'aide de cmd y PowerShell les caractéristiques de base, et le bizarre ^..*\...*$ regex est dérivé de ses résultats.

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

Sortie :

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

Comparez la définition de BaseName différente pour les fichiers et les dossiers :

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

Mi première réponse était basé sur un malentendu impardonnable :

Lire dir /? utiliser 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

~~

Autre approche : appliquer findstr regex かわりに dir *.* | findstr /V "<.*>"

6voto

feersum Points 160

Existe-t-il un moyen de ne lister que les fichiers avec un point ?

Vous pouvez faire correspondre les noms de fichiers avec un point en utilisant le caractère générique non documenté < qui correspond soit à une séquence de 0 ou plusieurs caractères dans le nom de base, soit à une séquence de 0 ou plusieurs caractères dans l'extension :

dir "<.<"

Rappelez-vous que < est également un métacaractère, vous devez donc le citer ou l'échapper lorsque vous l'utilisez dans un motif de la commande Shell.

1voto

user224190 Points 41

L'interpréteur de ligne de commande verra " . "comme "Tous les noms de fichiers de base" avec "toutes les extensions". Une extension vide est toujours une extension et seront donc comparés et renvoyés avec la liste. Comme d'autres l'ont expliqué, il s'agit d'un héritage des versions antérieures de Windows et de MS-DOS.

Si vous vous contentez de chercher à l'aide de PowerShell, il est beaucoup plus facile de trouver ces fichiers. Notez que dans PowerShell, "dir" est un alias pour la cmdlet "Get-ChildItem".

Pour trouver tous les fichiers (pas les répertoires/dossiers) qui ont une extension (par exemple "monfichier.txt", mais pas "FileWithNoExt") :

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

le commutateur "-af" est un raccourci pour "-File" qui restreint les objets retournés aux fichiers uniquement. "-ad" n'obtiendrait que les répertoires. L'option " \. "signifie "un caractère de point littéral". Sans la barre oblique inverse, le point correspondrait à n'importe quel caractère, conformément à la règle de la regex standard.

Pour obtenir tous les fichiers où il y a un point dans le nom sans l'extension, ainsi qu'une extension (par exemple "monDocument_v1.1.doc" mais pas "monfichier.txt") :

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

Notez cependant que cela exclura un fichier dont le nom est du type ".archive" avec un point précédent. Ceci est dû au fait qu'il est traité comme n'ayant pas de nom de base et une extension de "archive". Si vous voulez les inclure :

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

Ici, le modèle de correspondance dit "Un point littéral, OR(|) BeginningOfString(^) suivi de EndOfString($) (c'est-à-dire une chaîne vide)". Puisqu'un fichier ne peut pas avoir à la fois un nom de base vide et il trouvera les fichiers commençant par un point.

-2voto

Rahul Kant Points 1

Si vous tapez la commande ci-dessus, alors voici : * (c'est un joker qui signifie n'importe quelle séquence de caractères) suivi d'un point(.) suivi de * ceci pourrait être interprété comme montrant tous les fichiers qui ont un nom comme (toute séquence de caractères).(toute séquence de caractères) ce qui signifie également qu'il faut afficher tous les fichiers, quelle que soit leur extension.

SistemesEz.com

SystemesEZ est une communauté de sysadmins où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.

Powered by:

X