CMD: *. * Или просто *?

47

Еще в 1990-х я использовал « *.*» для обозначения любого имени файла в MS-DOS, но я видел больше сценариев, использующих только « *» в эти дни. Имеет ли это какое-то значение, какой я использую?

Foebane
источник
9
Хотя это правда, *и *.*теперь они эквивалентны для cmdвнутренних команд и современных утилит командной строки, некоторые старые утилиты, которые принимают параметры маски файла, могут использовать более старые функции сопоставления файлов, и для них маски не будут эквивалентны.
AFH
@AFH Я не думаю, что токены равны. *.*Маркер не должен возвращать extensionless файлов.
Tuskiomi
1
@tuskiomi - я бы согласился с вами, что *.* не следует возвращать файлы без расширений. К сожалению, это так. Смотрите ответ Гравити.
AFH

Ответы:

65

Имя и расширение файла были единым полем с тех пор, как в Windows 95 и NT 3.5 была введена поддержка «длинных имен файлов», и сопоставления с подстановочными знаками выполняются сразу для всего имени файла. В результате вы можете иметь имя файла без точек (возможно, редко для файлов, но очень часто встречающееся для папок / каталогов), и на первый взгляд *.*фактически не будет совпадать с такими файлами.

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

Но это не то, на что вы должны положиться; если вы пишете сценарии для современных версий Windows, следуйте их соглашениям, а не соглашениям MS-DOS. (Обратите внимание, что в Windows NT сценарии .bat больше не интерпретируются MS-DOS cmd.exe, а встроенной программой Win32.)


В Linux и различных других Unixen, имя и расширение никогда не были разделены в первую очередь, и нет никакой особой магии, чтобы сделать *.*работу, так *что это единственный выбор, который имеет смысл.

grawity
источник
14
«Давайте усложним фильтрацию файлов с расширениями! -Анонимный разработчик Microsoft
Джон Гамильтон
50
«Давайте разберем миллионы существующих пакетных сценариев для всех! Нет разработчика Microsoft, Ever
grawity
3
ISTR, что в некоторых старых версиях DOS, *будет соответствовать только именам файлов без расширения. «Безопасный» способ быть совместимым с обоими - использовать **.
Random832
8
ОП касается Windows, но поскольку вы упомянули Linux: в некоторых оболочках (например, Bash) *( по умолчанию ) не совпадает со скрытыми именами файлов (начиная с a .).
Флориан Брукер
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 , обеспечат согласованное подмножество поведения posixy.
shalomb
источник
Другое отличие состоит в том, что в CMD большинство программ фактически перенаправляют необработанный шаблон в ядро ​​(FindFirstFile), в то время как glob в Linux просто захватывает полный список и выполняет фильтрацию в пространстве пользователя.
grawity
Когда вы запускаете * в каталоге с миллионами файлов, команда будет жаловаться на слишком много параметров. В худшем случае он может молча опустить хвост списка. В этих случаях вам нужно передать две или более команд или сохранить список имен файлов в файле, чтобы другой процесс мог прочитать список.
Энрик Морской
3
@grawity Чтобы быть более точным, фильтрация выполняется драйвером файловой системы в Windows. Это особенно полезно в сетевых файловых системах (особенно в тех случаях, когда вы могли запустить линию 8 КБ в удаленной файловой системе), но это также означает, что вы не можете выполнять произвольный поиск, а также явно поддерживаемый поиск. Последствия этого неоднократно изучались в блоге Рэймонда Чена. FindFirstFileсам по себе является пользовательским режимом (и kernel32.dll, и ntdll.dll являются библиотеками пользовательского режима - это часть подсистемы Win32, а не ядра), но на самом деле он мало что делает.
Луаан
Ах, у меня сложилось впечатление, что FindFirstFile в значительной степени напрямую оборачивает одноименный системный вызов (например, как open (3) в libc просто оборачивает open (2) в ядре Linux).
благодарность
1
@cup: просто используйте кавычки, чтобы оболочка не расширяла глобусы, чтобы вы могли передавать их командам. например mmv "fred.*" "tom.#1". ( #1Вместо замены используется *, что позволяет переупорядочивать поля). mmvне устанавливается по умолчанию в большинстве систем, но часто используются другие инструменты пакетного переименования. См. Эту статью об этом , и stackoverflow.com/questions/417916/how-to-do-a-mass-rename .
Питер Кордес