Mengapa `dir *. *` Memberi saya semua file dan folder?

62

Ketika saya menjalankannya dir *.*menghasilkan hasil yang tidak terduga. Bahkan file dan folder tanpa titik di namanya terdaftar. Sebagai contoh

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

Mengapa demikian? Apakah ada cara untuk mendaftar hanya file dengan titik?

phuclv
sumber
19
Titik selalu ada, hanya saja tidak dicetak kecuali ada sesuatu yang mengikutinya. Dengan kata lain, Anda mungkin berpikir file bernama "ini file saya" tetapi diam-diam namanya "ini file saya." tanpa apa-apa setelah titik. Secara analog, Anda mungkin berpikir bahwa nama DNS untuk situs ini adalah "superuser.com", tetapi sebenarnya "superuser.com." tanpa apa-apa setelah titik kedua.
Todd Wilcox
12
@ToddWilcox hanya benar di DOS. Sistem file modern di Windows tidak lagi memiliki ekstensi namespace yang terpisah
phuclv
13
@ LưuVĩnhPhúc Subsistem Win32 memperlakukan nama file yang tidak mengandung .seperti yang mereka miliki .pada akhirnya untuk banyak tujuan, termasuk yang ini.
CodesInChaos
2
Folder yang tidak mengandung .karakter memiliki .karakter tersirat di akhir. - Anda dapat memiliki memiliki folder bernama "Blah.old" misalnya, dan kemudian akan memiliki ekstensi file 3 huruf tradisional; untuk penggunaan sehari - hari meskipun " Blah" sama dengan " Blah." apakah itu file atau folder.
BrainSlugs83
9
@ can-ned_food Todd Wilcox benar tentang DNS. Zona DNS root disebut secara harfiah ., dan label dalam nama DNS dipisahkan oleh .(dengan demikian nama zona DNS root adalah label panjang nol tunggal). Satu anak dari zona DNS root .adalah com., dan satu anak dari com.adalah superuser.com., dan seterusnya.
CVn

Jawaban:

115

Saya menulis jawaban ini karena OP telah menekankan bahwa:

Yang saya minati adalah mengapa *.*cocok dengan semua file, sebagaimana dinyatakan dalam pertanyaan

The DIRperintah berasal dari waktu ketika:

  1. Periode (.) Tidak diizinkan sebagai karakter dalam nama file atau folder
  2. Nama file dan folder dibatasi hingga 8 karakter untuk nama dan 3 karakter untuk ekstensi

Oleh karena itu, dengan standar itu, *.*berarti apa pun nama dan ekstensi apa pun . Itu tidak berarti string yang mengandung ".", Yang mungkin atau mungkin tidak memiliki karakter sebelum atau sesudah "." .

Kebijakan Microsoft menjaga kompatibilitas ke belakang. Oleh karena itu, interpretasi *.*tersebut dipertahankan.

Tetapi di Windows PowerShell, *.*berarti string yang berisi ".", Yang mungkin atau mungkin tidak memiliki karakter sebelum atau sesudah "." .

jpaugh
sumber
25
Sistem file asli bahkan tidak menyimpan periode itu sendiri pada disk, hanya 11 karakter yang membentuk sisa nama.
Tn. Lister
7
Perlu dicatat bahwa file dan folder tanpa ekstensi masih dianggap memiliki ekstensi kosong . Oleh karena itu, folder bernama " Folder.", dan folder bernama " Folder" dinamai hal yang sama, sejauh menyangkut windows.
BrainSlugs83
2
@ Tuan menarik. Bagaimana nama file FS store lama suka AA.BBdengan <8 di bagian pertama dan <3 di ekstensi? Apakah itu hanya pad dengan spasi?
Kelvin
3
@ Selvin ya kedua bagian itu berlapis ruang secara terpisah.
plugwash
12

Mengapa demikian?

Orang dapat menemukan jawaban untuk " Mengapa begitu? " Dalam artikel Wildcard :

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)

...

Aturan pencocokan wildcard

  • *Umumnya cocok dengan 0 karakter atau lebih, dengan satu pengecualian (lihat aturan berikutnya). Kartu liar non-serakah bebas untuk mencocokkan sebanyak atau sesedikit karakter yang diperlukan untuk sisa topeng untuk mencocokkan.

  • *.Di akhir mask cocok dengan 0 karakter atau lebih kecuali untuk {dot}. Dalam kenyataannya, aturan berlaku dengan sejumlah {dot} dan {spasi} karakter antara * dan terminal {dot}. Ekspresi reguler untuk istilah ini adalah"[*][. ]*[.]$"

  • ?Cocokkan 0 atau satu karakter, kecuali untuk {dot}. Satu-satunya waktu yang cocok dengan 0 karakter adalah ketika cocok dengan akhir nama, atau posisi sebelum {dot}. Tanda tanya juga dapat digunakan lebih dari satu kali untuk mencocokkan lebih dari satu karakter.

Implikasi . The terakhir {dot} dalam file / nama folder memisahkan nama dasar dan ekstensi. Begitu

  • dir *.menampilkan semua item tanpa ekstensi , dan
  • dir *.*menampilkan semua item dengan ekstensi nol atau lebih karakter .

Sebenarnya, dir *.menampilkan semua item tanpa titik ( .) dalam nama . (BTW, File Penamaan, Paths, dan Namespaces artikel MSDN mengatakan secara eksplisit bahwa " dapat diterima untuk menentukan periode sebagai karakter pertama dari nama ".)

Apakah ada cara untuk mendaftar hanya file dengan titik?

Saya kira tidak. Namun, ada solusi dengan ekspresi reguler yang pas.

PowerShell (solusi lingkup penuh jika digunakan dalam konsol Powershell):

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

Cmd (hanya ide, mungkin memerlukan elaborasi):

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

Tambahan: bonus dan penjelasan

Tebakan intuitif yang Namedigabungkan BaseNamedan Extension tidak berlaku . Script berikut membuktikannya menggunakan cmddan PowerShellfitur inti, dan regex aneh ^..*\...*$ berasal dari hasil itu.

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

Keluaran :

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

Bandingkan definisi BaseNameproperti, berbeda untuk file dan folder:

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

Jawaban asli saya didasarkan pada kesalahpahaman yang tak termaafkan:

Baca dir /?, gunakan 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

Pendekatan lain: terapkan findstrregex sebagaidir *.* | findstr /V "<.*>"

JosefZ
sumber
Yang saya minati adalah mengapa *.*cocok dengan semua file , seperti yang dinyatakan dalam pertanyaan
phuclv
Saya khawatir saran alternatif Anda (findstr) tidak menemukan folder yang dimulai dengan .sejenisnya .dbus-keyrings, .VirtualBoxdan .vscode.
22
Jadi dir /A:-Ddaftar hanya file yang senang?
Quentin
4
"Apakah ada cara untuk mendaftar hanya file dengan titik?" dir /A:-Dsalah. 1 / daftar file tanpa ekstensi. 2 / tidak mencantumkan direktori yang memiliki .nama mereka (sah menurut hukum)
DavidPostill
3
omg ... sudah puluhan tahun sejak saya terakhir melihat "@echo off"
rupps
7

Apakah ada cara untuk mendaftar hanya file dengan titik?

Anda dapat mencocokkan nama file dengan sebuah titik dengan menggunakan wildcard tidak berdokumen <, yang cocok dengan urutan 0 atau lebih karakter dalam nama dasar atau urutan 0 atau lebih karakter dalam ekstensi:

dir "<.<"

Ingat itu <juga merupakan metacharacter, jadi Anda perlu mengutip atau menghindarinya setiap kali menggunakannya dalam pola dari command shell.

feersum
sumber
1
luar biasa. Ini wildcard berdokumen memang ada
phuclv
1

Penerjemah Baris Perintah akan melihat " . " Sebagai "Semua nama file dasar" dengan "semua ekstensi". Ekstensi kosong masih merupakan ekstensi , jadi akan dicocokkan dan dikembalikan dengan daftar. Seperti yang dijelaskan orang lain, ini adalah hangover dari versi Windows dan MS-DOS sebelumnya.

Jika Anda senang melihat menggunakan PowerShell, menemukan file-file ini jauh lebih mudah. Perhatikan bahwa di PowerShell, "dir" adalah alias untuk cmdlet "Get-ChildItem".

Untuk menemukan semua file (bukan direktori / folder) yang memiliki ekstensi (mis. "Myfile.txt", tetapi bukan "FileWithNoExt"):

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

switch "-af" adalah kependekan dari "-File" yang membatasi objek yang dikembalikan ke file saja. "-ad" hanya akan mendapatkan direktori. "\." berarti "karakter titik literal". Tanpa garis miring terbalik, titik akan cocok dengan karakter apa pun, sesuai regex standar.

Untuk mendapatkan semua file di mana ada titik dalam nama tanpa ekstensi, serta ekstensi (mis. "MyDocument_v1.1.doc" tetapi bukan "myfile.txt"):

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

Namun perlu dicatat, bahwa ini akan mengecualikan file dengan nama seperti ".archive" dengan titik sebelumnya. Ini karena dianggap tidak memiliki nama dasar dan ekstensi "arsip". Jika Anda ingin memasukkan ini:

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

Di sini, pola kecocokan mengatakan "Titik literal, OR (|) BeginningOfString (^) diikuti oleh EndOfString ($) (yaitu string kosong)". Karena file tidak dapat memiliki nama samaran dan ekstensi yang kosong , ia akan menemukan file yang dimulai dengan titik.

Dave_J
sumber
di PowerShell ls *.*sudah cukup, karena banyak orang lain telah menjawab sebelum Anda
phuclv
-2

Jika Anda mengetik perintah di atas, maka di sini: * (ini adalah kartu liar yang berarti urutan karakter) diikuti oleh titik (.) Diikuti oleh * ini dapat diartikan sebagai menunjukkan semua file yang memiliki nama seperti (urutan karakter apa pun) ) (urutan karakter apa pun) yang selanjutnya berarti menampilkan semua file dengan ekstensi apa pun.

Rahul Kant
sumber
1
Lalu mengapa Program Filesdimasukkan dalam daftar? Itu tidak cocok dengan polanya <sequence of characters>.<sequence of characters>.
gronostaj
Anggap lebih sebagai <Urutan nol atau lebih karakter> Itu sebabnya ia juga akan mengambil file bernama ".info" di mana nama dasarnya kosong.
Dave_J