6

В Windows 7 у меня есть каталог, содержащий следующие четыре файла:

  • xxx.txt
  • xxx.txt2
  • xxx2.txt
  • xxx2.txt2

Поскольку файл имеет более 3 символов в качестве расширения файла, поведение подстановочного знака * кажется странным:

dir *.txt

10/13/2014  04:14 PM                 6 xxx.txt
10/13/2014  04:17 PM                 6 xxx2.txt
10/13/2014  04:17 PM                 6 xxx2.txt2
10/13/2014  04:14 PM                 6 xxx.txt2
           4 File(s)             24 bytes
           0 Dir(s)   6,660,980,736 bytes free

Я ожидаю увидеть только два файла с расширением txt, а не те, что с txt2 (как на компьютере с Linux). MS-DOS игнорирует усечение расширения файла до 3 символов или автоматически добавляет еще один подстановочный знак в конце? Если я хочу удалить только файлы с расширением txt, а не с txt2, какую команду мне использовать? Спасибо

3 ответа3

7

Вы не используете MS-DOS; он даже не допускает расширения файлов длиннее 3 символов. Вы используете командную строку Windows - в частности, оболочку cmd.exe .

Но Windows действительно старается поддерживать совместимость с программами той эпохи. Таким образом, вплоть до Windows 8 (или чего-то подобного) все файлы с более длинными расширениями имеют псевдоним, у которого расширение урезано, вместе с самим именем.

Если вы запустите dir /x , вы, вероятно, увидите, что каждому файлу присвоено "короткое имя", которое ограничено 8+3 символами, как в MS-DOS и 16-битной Windows.

Эти имена присутствуют на тот случай, если пользователь захочет, скажем, обновить до Windows 95 и по-прежнему получать доступ к своим файлам через программы, изначально написанные для Windows 3.1 - поэтому запуск 16-разрядной программы не приведет к сбою, а просто покажет C:\PROGRA~1 и C:\MYDOCU~1\CALENDAR.TXT вместо C:\Program Files и C:\My Documents\Calendar.txt .

(И да, некоторые люди действительно использовали старое 16-битное программное обеспечение даже в дни Windows XP/Vista ... Однако я уверен, что Windows 8 по умолчанию отключает "короткие имена". Возможно, поэтому @EBGreen не видит ту же "проблему" ...)


Еще одна вещь, которую стоит учесть, это то, что старая оболочка Windows, cmd.exe , вырастила немало причуд и исправлений совместимости сама по себе. Например, из-за того, как MS-DOS совпал с именами файлов, dir .txt означал то же самое, что и dir *.txt , хотя это и не было преднамеренным. Но люди привыкли к более короткому синтаксису, и хотя сама операционная система Windows больше не рассматривает .txt как подстановочный знак, cmd.exe прежнему принимает этот синтаксис. (Команда dir сама по себе не является программой, а встроена в оболочку.)

(Точно так же в связанной статье описывается еще одна странная особенность - имена файлов Windows могут вообще не иметь расширения, но люди действительно привыкли печатать *.* , Поэтому это означает то же самое, что и * а одиночная точка игнорируется.)

3

Я не могу сказать вам, почему это так работает. Это довольно странно. Я могу вам сказать, что Powershell (который вы должны иметь на машине) работает так, как вы ожидаете. В PowerShell:

PS I:\temp\test> ls


    Directory: I:\temp\test


Mode                LastWriteTime     Length Name
----                -------------     ------ ----
-a---        10/13/2014   9:29 AM          3 bar.txt
-a---        10/13/2014   9:29 AM          3 bar.txt2
-a---        10/13/2014   9:29 AM          3 foo.txt
-a---        10/13/2014   9:29 AM          3 foo.txt2

PS I:\temp\test> ls *.txt


    Directory: I:\temp\test


Mode                LastWriteTime     Length Name
----                -------------     ------ ----
-a---        10/13/2014   9:29 AM          3 bar.txt
-a---        10/13/2014   9:29 AM          3 foo.txt
2

grawity правильно определила, что поведение связано с короткими именами файлов. Файловые маски сравниваются как с длинными, так и с короткими именами.

Полные правила сопоставления подстановочных знаков с именами файлов доступны в разделе "sourceMask" в разделе Как команда RENAME Windows интерпретирует подстановочные знаки?

Вы можете получить желаемый результат DIR, отправив в FINDSTR:

dir *.txt* | findstr /vrix "[0-9].*\.txt[^.][^.]*"

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .