CMD: *. * Або просто *?


47

Ще в 1990-х я б " *.*" використовував для представлення будь-якого імені файлу в MS-DOS, але я бачив більше сценаріїв, що використовуються саме *сьогодні. Чи насправді має будь-яке значення, який я використовую?


9
Хоча це правда , що *і *.*в даний час еквівалентні для cmdвнутрішніх команд і сучасних утиліт командного рядка, деякі старі утиліти , які приймають параметри маски файлів можуть використовувати старі функції зіставлення файлів, а також для них маски не будуть еквівалентні.
AFH

@AFH Я не думаю, що жетони рівні. *.*Маркер не повинен повертати extensionless файлів.
тускіоми

1
@tuskiomi - Я погодився б із вами, що *.* не слід повертати файли без розширень. На жаль, так і є. Дивіться відповідь Grawity.
AFH

Відповіді:


65

Ім’я та розширення файлу були єдиним полем з тих пір, як Windows 95 та NT 3.5 запровадили підтримку «довгого імені файлу», а підстановки підстановок проти всього імені файлу одночасно. Як результат, ви можете мати ім’я файлу без крапки (можливо, це рідко для файлів, але дуже поширене для папок / каталогів), і на перший погляд *.*насправді вони не відповідають таким файлам.

Старі сценарії, які використовуються *.* , все ще працюватимуть через код сумісності - якщо підстановочний знак закінчується .*, ця частина ігнорується ОС. (Тож якщо ви хотіли спеціально відповідати файлам із розширенням, я думаю, вам це знадобиться *.?*.)

Але це не те, на що слід покладатися; якщо ви пишете сценарії для сучасних версій Windows, дотримуйтесь їх конвенцій, а не MS-DOS. (Зауважте, що, як і для Windows NT, .bat сценарії більше не інтерпретуються MS-DOS cmd.exe, а рідною програмою Win32.)


В Linux і різних інших Unixen, ім'я та розширення ніколи не були розділені в першу чергу, і НЕ який - або особлива магія , щоб зробити *.*роботу, так що *це єдиний вибір , який має сенс.


14
"Давайте будемо складніше фільтрувати файли з розширеннями! Так!" -Анонімний розробник Microsoft
Джон Гамільтон

50
"Давайте порушимо мільйони існуючих пакетних сценаріїв для всіх! Так!" -Нема Microsoft Developer, Ever
grawity

3
ISTR, що на деяких старих версіях DOS, *буде відповідати лише назви файлів без розширення. «Безпечним» способом бути сумісним з обома було використовувати **.
Випадково832

8
ОП стосується Windows, але оскільки ви вже згадали Linux: У деяких оболонках (Bash, наприклад), *вони ( за замовчуванням ) не відповідають прихованим іменам (починаючи з а .).
Флоріан Брюкер

4
Для деяких значень "рівня ОС" ... Це дійсно концепція оболонки (Explorer) і в Windows - ядро ​​не хвилює .exe у виконуваних файлах, ні про що інше. Чи є Windows Explorer більш "рівнем ОС", ніж, наприклад, Nautilus в Linux, можна сперечатися.
grawity

11

Це, ймовірно , варто згадати про те , що unixy / posixy оболонка , таких як оболонки Борна, Баш, KSH, Zsh, і т.д. зробити підстановлювальний розширення (з GLOB символів подобаються *, ?, [range], [!range]та інші розширення , як дужки і розширені грудки) скласти список аргументів , перш ніж команда виконується. Таким чином, це розширення виконується оболонкою, а не командою, для якої це можуть бути аргументи.

тобто оболонка відповідає за те *, за що *.*розширюється

 $ 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

Це не так у CMD (і аналогічно для утиліти powershell ), оскільки він переносить символи глобально дослівно у виконану команду - і тому розширення є обов'язком команди / утиліти, а не оболонки. Отже, в остаточному підсумку, що *.*або *засоби залишається утиліті, залишаючи її відповідати (або ні) конвенціям - саме тому утиліти CMD, як dir *.*і відповідні (можливо, неправильно, але зберігають очікування) файли без розширень.

Я вважаю, що безпечно підсумувати цей спосіб.

  • Під CMD це залежить від корисності.
  • У програмі PowerShell утиліти, які використовують клас WildCardPattern , забезпечуватимуть послідовний підмножина позікси-поведінки.

Ще одна відмінність полягає в тому, що в CMD більшість програм насправді пересилає необроблені символи до ядра (FindFirstFile), тоді як глобальний на Linux просто захоплює повний список і виконує фільтрацію в просторі користувачів.
grawity

Коли ви запускаєте * у каталозі з мільйоном файлів, команда скаржиться на занадто багато параметрів. У гіршому випадку це мовчки може скинути хвіст списку. У цих випадках вам потрібно передати дві або більше команд або зберегти список імен файлів у файлі, щоб інший процес міг прочитати список.
Enric Naval

3
@grawity Щоб бути більш точним, фільтрування виконується драйвером файлової системи в Windows. Це особливо корисно в мережевих файлових системах (особливо тоді, коли ви могли працювати з 8-кілограмовою лінією у віддаленій файловій системі), але це також означає, що ви не можете здійснювати як довільний пошук, так і явно підтримуваний пошук. Наслідки цього були багато разів досліджені в блозі Реймонда Чена. FindFirstFileсам по собі користувальницький режим (і kernel32.dll, і ntdll.dll - це бібліотеки в режимі користувача - це частина підсистеми Win32, а не ядро), але насправді це не дуже багато.
Луаан

Ах, у мене було враження, що FindFirstFile в значній мірі безпосередньо загорнув аналогічну назву syscall (як, наприклад, як open (3) у libc просто завершує відкриття (2) у ядрі Linux).
grawity

1
@cup: Просто використовуйте лапки, щоб оболонка не розширювала глобуси, щоб ви могли передавати їх командам. напр mmv "fred.*" "tom.#1". (Заміна використовує #1замість *, що має перевагу в тому, що дозволяє повторно замовляти поля). mmvне встановлено за замовчуванням у більшості систем, але інші інструменти пакетного перейменування часто є. Дивіться цю статтю про це та stackoverflow.com/questions/417916/how-to-do-a-mass-rename .
Пітер Кордес
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.