CMD: *. * Atau hanya *?

47

Kembali pada 1990-an, saya akan menggunakan " *.*" untuk mewakili nama file apa pun di MS-DOS, tapi saya sudah melihat lebih banyak skrip menggunakan " *" saja belakangan ini. Apakah itu benar-benar membuat perbedaan mana yang saya gunakan?

Foebane
sumber
9
Meskipun benar bahwa *dan *.*sekarang setara untuk cmdperintah internal dan utilitas baris perintah modern, beberapa utilitas yang lebih tua yang mengambil parameter mask file dapat menggunakan fungsi pencocokan file yang lebih lama, dan bagi mereka masker tidak akan setara.
AFH
@ EH Saya tidak berpikir bahwa token sama. The *.*Token tidak harus kembali file extensionless.
tuskiomi
1
@tuskiomi - Saya setuju dengan Anda bahwa *.* tidak boleh mengembalikan file tanpa ekstensi. Sayangnya itu terjadi. Lihat jawaban Grawity.
AFH

Jawaban:

65

Nama file dan ekstensi telah menjadi bidang tunggal sejak Windows 95 dan NT 3.5 memperkenalkan dukungan "nama file panjang", dan kecocokan wildcard dilakukan terhadap seluruh nama file sekaligus. Akibatnya, Anda dapat memiliki nama file tanpa titik di dalamnya (mungkin jarang untuk file, tetapi sangat umum untuk folder / direktori) dan sekilas *.*tidak akan benar-benar cocok dengan file tersebut.

Penggunaan skrip lama masih *.* akan berfungsi karena kode kompatibilitas - jika wildcard berakhir dengan .*, bagian itu diabaikan oleh OS. (Jadi jika Anda ingin secara khusus mencocokkan file dengan ekstensi, saya kira Anda perlu *.?*melakukannya.)

Tapi itu bukan sesuatu yang harus Anda andalkan; jika Anda menulis skrip untuk versi Windows modern, ikuti konvensi mereka, bukan konvensi MS-DOS. (Perhatikan bahwa pada Windows NT, skrip .bat tidak ditafsirkan oleh MS-DOS lagi tetapi oleh cmd.exe, program Win32 asli.)


Di Linux dan berbagai Unixen lainnya, nama & ekstensi tidak pernah terpisah sejak awal, dan tidak ada keajaiban khusus untuk *.*bekerja, jadi *adalah satu-satunya pilihan yang masuk akal.

grawity
sumber
14
"Mari kita buat lebih sulit untuk memfilter file dengan ekstensi! Yay!" -Pengembang Microsoft Anonim
John Hamilton
50
"Mari kita hancurkan jutaan skrip batch yang ada untuk semua orang! Yay!" -Tidak Ada Pengembang Microsoft, Pernah
grawity
3
ISTR yang pada beberapa versi lama DOS, *hanya akan cocok dengan nama file tanpa ekstensi. Cara 'aman' agar kompatibel dengan keduanya adalah menggunakan **.
Random832
8
OP adalah tentang Windows, tetapi karena Anda telah menyebutkan Linux: Dalam beberapa shell (Bash, misalnya), *apakah ( secara default ) tidak cocok dengan nama file tersembunyi (dimulai dengan a .).
Florian Brucker
4
Untuk beberapa nilai "OS level" ... Ini juga benar-benar sebuah konsep shell (Explorer) di Windows - kernel tidak peduli dengan .exe pada executable, atau yang lainnya. Apakah Windows Explorer lebih "tingkat OS" daripada misalnya Nautilus di Linux dapat diperdebatkan.
grawity
11

Itu mungkin layak disebutkan bahwa unixy yang / kerang posixy seperti shell Bourne, bash, ksh, zsh, dll melakukan ekspansi wildcard (karakter gumpal seperti *, ?, [range], [!range]dan ekspansi lainnya seperti kawat gigi, dan gumpalan diperpanjang) untuk mengkompilasi daftar argumen sebelum perintah dieksekusi. Jadi ekspansi ini dilakukan oleh shell bukan perintah yang menjadi argumennya.

yaitu Shell bertanggung jawab atas apa *, *.*memperluas ke

 $ ls
 file.csv  file.doc  file.pdf  file.txt  file.xlsx  zz-file-without-extension

 $ (set -xv; foo *)   # is actually expanded to the following
   + foo file.csv file.doc file.pdf file.txt file.xlsx zz-file-without-extension

 $ (set -xv; foo *.*)  # note this does not match `zz-file-without-extension`
   + foo file.csv file.doc file.pdf file.txt file.xlsx

Ini bukan kasus dalam CMD (dan juga untuk utilitas powershell ) karena ia meneruskan karakter glob secara verbatim ke dalam perintah yang dieksekusi - dan karenanya ekspansi adalah tanggung jawab perintah / utilitas dan bukan pada shell. Jadi pada akhirnya, apa *.*atau apa *yang tersisa untuk utilitas membiarkannya untuk menyesuaikan (atau tidak) dengan konvensi - itulah sebabnya utilitas CMD seperti dir *.*juga cocok (bisa dibilang salah mempertahankan harapan) file tanpa ekstensi.

Saya percaya aman untuk merangkum dengan cara ini.

  • Di bawah CMD itu tergantung pada utilitas.
  • Di bawah PowerShell, utilitas yang memanfaatkan WildCardPattern Class akan memberikan subset perilaku yang konsisten.
shalomb
sumber
Perbedaan lain adalah bahwa di bawah CMD, sebagian besar program benar-benar meneruskan wildcard mentah ke kernel (FindFirstFile), sementara glob di Linux hanya mengambil daftar lengkap dan melakukan penyaringan di userspace.
grawity
Ketika Anda menjalankan * pada direktori dengan sejuta file, perintah itu akan mengeluh terlalu banyak parameter. Dalam kasus terburuk, itu bisa diam-diam menjatuhkan ekor daftar. Dalam kasus tersebut, Anda perlu mem-pipe dua atau lebih perintah, atau menyimpan daftar nama file dalam file, sehingga proses lain dapat membaca daftar.
Enric Naval
3
@grawity Agar lebih akurat, pemfilteran dilakukan oleh driver sistem file pada Windows. Ini sangat berguna pada sistem file jaringan (terutama ketika Anda bisa menjalankan jalur 8 kb ke sistem file jarak jauh), tetapi ini juga berarti Anda tidak dapat melakukan pencarian sewenang-wenang serta pencarian yang didukung secara eksplisit. Implikasi dari ini telah dieksplorasi berkali-kali di blog Raymond Chen. FindFirstFileitu sendiri adalah mode pengguna (baik kernel32.dll dan ntdll.dll adalah pustaka mode pengguna - itu adalah bagian dari subsistem Win32, bukan kernel), tetapi tidak benar-benar berbuat banyak.
Luaan
Ah, saya mendapat kesan bahwa FindFirstFile cukup banyak langsung membungkus syscall bernama sama (seperti bagaimana open (3) di libc hanya membungkus terbuka (2) di kernel Linux).
grawity
1
@cup: Cukup gunakan tanda kutip untuk mencegah shell memperluas gumpalan, sehingga Anda dapat meneruskannya ke perintah. mis mmv "fred.*" "tom.#1". (Pengganti menggunakan #1bukan *, yang memiliki keuntungan membiarkan Anda memesan ulang bidang). mmvtidak diinstal secara default pada sebagian besar sistem, tetapi alat batch-rename sering. Lihat artikel ini tentang itu , dan stackoverflow.com/questions/417916/how-to-do-a-mass-rename .
Peter Cordes