Странное поведение команд 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.