Очевидно, что оболочка учитывает как короткое, так и длинное имя для подстановочного знака. Более подробное объяснение можно найти в ответе shf301 . Это прискорбно и, вероятно, осталось от Ye Olde Days из DOS, потому что это то, что cmd
пытается быть совместимым с чем-то вроде.
Несколько вариантов здесь:
Используйте
forfiles
, у которого есть другая семантика для расширения подстановочного знака:forfiles /m *.txt /c "cmd /c copy @file foo"
Это доступно по крайней мере на Vista и позже.
Используйте
for
и проверьте расширение:for %a in (*.txt) do @if %~xa==.txt @copy "%i" foo
К сожалению,
for
также возвращает любые файлы с.txt~
расширением, когда используется только подстановочное расширение. Вот почему нам нужно проверить расширение во второй раз.Используйте
xcopy
. Хотяxcopy
для расширения с подстановочными знаками используется та же семантика, что и для оболочки, вы можете дать ему файл с именами, которые следует игнорировать:echo .txt~>tmpfile xcopy *.txt foo /exclude:tmpfile del tmpfile
Используйте
robocopy
. Хотяrobocopy
для расширения подстановочных знаков используется та же семантика, что и для оболочки, вы можете указать список файлов / подстановочных знаков, которые следует игнорировать:robocopy . foo *.txt /XF *.txt~
Используйте
for
,dir
иfindstr
в соответствующей комбинации. Это, по сути, просто отфильтровывает все строки, которые имеют~
в конце и работает с остальными.if
Вариант выше был более элегантным, я думаю.for /f "usebackq delims=" %i in (`dir /b *.txt ^| findstr /r "[^~]$"`) do @copy "%i" foo
Просто для полноты: PowerShell:
Copy-Item *.txt foo