Странное поведение команд DIR для Windows
Я обнаружил это совершенно случайно, ища файл с номером в названии. Когда я печатаю:
dir
*
номер *
(где число представляет любое число от 0 до 9 и без пробелов между звездочками и числом)
в командной строке cmd.exe, он возвращает различные файлы, которые не отображаются ни в одном, чтобы соответствовать критериям поиска. Что странно, это зависит от каталога, некоторые числа будут работать, а не другие. Например, в каталоге, связанном с веб-сайтом, я печатаю следующее:
dir *4*
и возвращается:
Directory of C:\Ampps\www\includes\pages
04/30/2012 03:55 PM 153 inventory_list_retrieve.php
06/18/2012 11:17 AM 6,756 ix.html
06/19/2012 01:47 PM 257,501 jquery.1.7.1.js
3 File(s) 264,410 bytes
0 Dir(s) 362,280,906,752 bytes free
Это просто не имеет никакого смысла для меня. Любая подсказка?
Вопрос ставится на stackOverflow, потому что команда DIR часто сочетается с FOR в пакетных программах. Странное поведение DIR, по-видимому, делает пакетные программы потенциально ненадежными, если они используют команду DIR.
Изменить: (дополнительная заметка). Хотя прошло много времени, я обнаружил еще одну причуду с этим, что почти стоило мне большой работы. Я хотел удалить все файлы .htm
в конкретном дереве каталогов. Я понял перед этим, что *.htm
соответствует файлам .html
. Кроме того, *.man
соответствует .manifest
, и, возможно, есть другие. Удаление всех файлов .html
в этом конкретном каталоге было бы, по меньшей мере, расстраивающим.
Ответы
Ответ 1
Дикие карты в командной строке сопоставляются как с длинным именем файла, так и с коротким "8.3" именем, если оно присутствует. Это может вызвать неожиданности.
Чтобы просмотреть короткие имена, используйте команду /X
для команды DIR
.
Обратите внимание, что это поведение никак не зависит от команды DIR
и может привести к другим (часто неприятным) неожиданностям, когда дикая карта соответствует более чем ожидаемой для любой команды, например DEL
.
В отличие от оболочек * nix, замена шаблона файла списком совпадающих имен выполняется в каждой команде и не реализуется самой оболочкой. Это может означать, что разные команды могут реализовывать разные шаблоны шаблонов wild card, но на практике это довольно редко, так как Windows предоставляет вызовы API для поиска в каталоге файлов, соответствующих шаблону, и большинство программ используют эти вызовы очевидным образом. Для программ, написанных на C или С++ с использованием "обычных" инструментов, это расширение предоставляется "бесплатно" библиотекой времени выполнения C с использованием API Windows.
В рассматриваемом API Windows FindFirstFile()
и его близких родственниках FindFirstFileEx()
, FindNextFile()
и FindClose()
.
Как ни странно, хотя документация для FindFirstFile()
описывает параметр lpFileName как "каталог или путь", а имя файла, которое может содержать подстановочные знаки, например, звездочку (*
) или знак вопроса (?
) "он никогда не определяет, что означают символы *
и ?
.
Точный смысл шаблона файла имеет историю в операционной системе CP/M начиная с начала 1970-х годов, которая сильно повлияла (некоторые могут сказать "был скопирован прямо" вместо "влияния" здесь) на дизайн MSDOS. Это привело к ряду "интересных" артефактов и поведения. Некоторые из них на конце DOS спектра описаны в
Ответ 2
Угу. Вы увидите, что он также ищет короткие имена, если вы попробуете это:
dir /x *4*
(/x для коротких имен)
для фильтрации имен файлов используйте:
dir /b | find "4"
Ответ 3
Цитата из ответа RBerteig:
Обратите внимание, что это поведение никак не связано с командой DIR, и может привести к другим (часто неприятным) неожиданностям, когда дикая карта соответствует более ожидаемым значениям для любой команды, например DEL.
Вышесказанное верно даже для команды FOR, что очень неприятно.
for %A in (*4*) do @echo %A contains a 4
также будет искать короткие имена. Решением снова будет использование FIND или FINDSTR для более точного определения имен.
for %A in (*) do @echo %A | >nul findstr 4 && echo %A contains a 4
Примечание - измените% A на %% A, если используете команду в пакетном файле.
Объединение FOR с FINDSTR может быть универсальным методом для безопасного использования любой команды, которая сталкивается с проблемами с короткими именами файлов. Просто замените ECHO на командную задачу, такую как COPY или DEL.
Ответ 4
Похоже, что dir-команда выполняет поиск также коротких (8.3-way) имен файлов под капотом.
Когда я вызываю dir *1*
, это то, что я получаю:
Volume in drive C is System
Volume Serial Number is F061-0B78
Directory of C:\Users\Piotrek\Desktop\Downloads
2012-05-20 17:33 23 639 040 gDEBugger-5_8.msi
2012-05-20 17:30 761 942 glew-1.7.0.zip
2012-05-20 17:11 9 330 176 irfanview_plugins_433_setup.exe
2012-05-24 20:17 4 419 192 SumatraPDF-2.1.1-install.exe
2012-05-15 22:55 3 466 248 TrueCrypt Setup 7.1a.exe
5 File(s) 1 127 302 494 bytes
Существует файл gDEBugger-5_8.msi
среди перечисленных, который, по-видимому, не имеет в нем символа 1
.
Все становится ясным, когда я использую переключатель /X
с командой dir, что делает dir использовать имена файлов 8.3. Вывод команды dir /X *1*
:
Volume in drive C is System
Volume Serial Number is F061-0B78
Directory of C:\Users\Piotrek\Desktop\Downloads
2012-05-20 17:33 23 639 040 GDEBUG~1.MSI gDEBugger-5_8.msi
2012-05-20 17:30 761 942 GLEW-1~1.ZIP glew-1.7.0.zip
2012-05-20 17:11 9 330 176 IRFANV~1.EXE irfanview_plugins_433_setup.exe
2012-05-24 20:17 4 419 192 SUMATR~1.EXE SumatraPDF-2.1.1-install.exe
2012-05-15 22:55 3 466 248 TRUECR~1.EXE TrueCrypt Setup 7.1a.exe
5 File(s) 1 127 302 494 bytes
Цитата из dir help:
/X This displays the short names generated for non-8dot3 file
names. The format is that of /N with the short name inserted
before the long name. If no short name is present, blanks are
displayed in its place.