Lorsque je lance dir *.*
, cela produit des résultats inattendus. Même les fichiers et les dossiers sans nom dans leur nom 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 donc? Est-il possible de ne lister que les fichiers avec un point?
J'écris cette réponse parce que OP a souligné que:
ce qui m'intéresse est pourquoi
*.*
correspond à tous les fichiers, comme indiqué dans la question
La commande DIR
vient d'un moment où:
Par conséquent, selon cette norme, *.*
signifiait quels que soient le nom et l’extension . Cela 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 préserve la compatibilité ascendante. Par conséquent, cette interprétation de *.*
est conservée.
Mais dans Windows PowerShell, *.*
signifie une chaîne contenant un ".", Qui peut contenir ou non des caractères avant ou après le "." .
On pourrait trouver une réponse à "Pourquoi est-ce que c'est?" 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 générique
*
Correspond généralement à 0 caractère ou plus, à une exception près (voir la règle suivante). Le caractère générique non gourmand est libre de faire correspondre le nombre de caractères nécessaire pour que le reste du masque corresponde.
*.
À la fin du masque correspond à 0 caractère ou plus, à l'exception de {point}. En réalité, la règle s'applique avec un nombre quelconque de caractères {point} et {espace} entre le * et le terminal {point}. L'expression régulière pour ce terme est"[*][. ]*[.]$"
?
Match 0 ou un caractère, sauf pour {dot}. La seule fois où il correspond à 0 caractère, c'est lorsqu'il correspond à la fin du nom ou à la position précédant un {point}. Le point d'interrogation peut également être utilisé plusieurs fois pour faire correspondre plusieurs caractères.
Implication. Le dernier _ {point} d'un nom de fichier/dossier sépare nom de base et extension. Alors
dir *.
affiche tous les éléments avec pas d’extension , etdir *.*
affiche tous les éléments avec extension de zéro caractère ou plus .À proprement parler, dir *.
affiche tous les éléments avec sans période (.
). (BTW, Nommer des fichiers, des chemins et des espaces de noms MSDN article dit explicitement que "il est acceptable de spécifier un point comme premier caractère d'un nom}". "
Je ne pense pas. Toutefois, il existe une solution de contournement avec une expression régulière approprié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, peut nécessiter quelques explications):
:: 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
Une hypothèse intuitive selon laquelle Name
est concaténée BaseName
et Extension
ne tient pas . Le script suivant le prouve en utilisant cmd
et PowerShell
, et le regex bizarre^..*\...*$
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
Compare définition de la propriété 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};}
Mon réponse originale était basé sur un malentendu impardonnable:
Lisez dir /?
, utilisez 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
Une autre approche: apply findstr
regex as dir *.* | findstr /V "<.*>"
Est-il possible 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 à une séquence de 0 caractères ou plus dans le nom de base ou à une séquence de 0 caractères ou plus dans l'extension:
dir "<.<"
N'oubliez pas que <
est également un métacaractère. Vous devez donc le citer ou l'échapper si vous l'utilisez dans un motif de la commande Shell.
L'interpréteur de ligne de commande verra ". " comme "Tous les noms de fichiers de base" avec "toutes les extensions". Une extension vide est est toujours une extension , elle sera donc mise en correspondance et retournée à la liste. Comme d'autres l'ont expliqué, il s'agit d'une survivance de versions antérieures de Windows et de MS-DOS.
Si vous préférez utiliser PowerShell, il est beaucoup plus facile de rechercher ces fichiers. Notez que dans PowerShell, "dir" est un alias de la cmdlet "Get-ChildItem".
Pour rechercher tous les fichiers (pas les répertoires/dossiers) ayant une extension (par exemple, "myfile.txt", mais pas "FileWithNoExt"):
dir -af | Where {$_.Name -match "\."}
le commutateur "-af" est un raccourci pour "-Fichier" qui limite les objets renvoyés aux fichiers. "-ad" n'obtiendrait que des répertoires. Le "\." signifie "un caractère littéral". Sans la barre oblique inverse, le point correspondrait à n'importe quel caractère, comme dans les expressions rationnelles standard.
Pour obtenir tous les fichiers contenant un point dans le nom sans l'extension, ainsi qu'une extension (par exemple, "myDocument_v1.1.doc" mais pas "myfile.txt"):
dir -af | Where {$_.BaseName -match "\."}
Notez cependant que cela exclura un fichier avec le nom tel que ".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 "archive". Si vous souhaitez inclure ces éléments:
dir -af | Where {$_.BaseName -match "\.|^$"}
Ici, le motif de correspondance indique "Un point littéral, OU (|) BeginningOfString (^) suivi de EndOfString ($) (c'est-à-dire une chaîne vide)". Comme un fichier ne peut pas avoir à la fois une extension vide - et , il trouvera les fichiers commençant par un point.