33

Иногда неспособность оболочки cmd расширять пути подстановки может быть неудобством. Мне пришлось передать 100 файлов из каталога в программу, и я не смог набрать * .ext. Вместо этого я использовал msw 'ls', чтобы выгрузить список в файл, а затем заменил символы новой строки пробелами, скопировал и вставил в cmd. Совсем кошмар.

Я подозреваю, что ответ будет отрицательным, но кто-нибудь имел дело с этим или придумал какой-нибудь способ облегчить это?

6 ответов6

17

DOS и, следовательно, Windows cmd.exe , никогда не поддерживали расширение подстановочных знаков в оболочке. Это всегда было за приложением, чтобы сделать расширение.

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

  • Используйте цикл FOR для запуска некоторых команд со всеми интересующими вас файлами.
  • Используйте dir /b > list.txt чтобы использовать команду dir для выполнения раскрытия и поместить список файлов в текстовый файл (тогда вы могли бы использовать что-то вроде формулы Excel, если вы действительно хотите создать список команд для вставьте в cmd , или вы можете использовать Excel для транспонирования ячеек, чтобы все имена файлов были в одной строке.)
9

Просто используйте Powershell, который предустановлен в Windows 7. Powershell способен запускать команды cmd и понимает подстановочные знаки в любом месте пути.

Чтобы запустить Powershell, просто введите "powershell" в поле поиска в меню "Пуск" и нажмите Enter.


Если приложение ожидает строку со всеми именами файлов, это правильный сценарий:

$delimiter = " "
[string]$files = $nothing ; ls *.txt | % { $files += $_.fullname + $delimiter } ; application.exe $files

Замените $delimiter = " " на $delimiter = "," если ваше приложение ожидает разделенный запятыми список имен файлов.

Объяснение кода:

  • [string]$files = $nothing - создает пустую переменную типа string
  • ; - это разделитель для нескольких команд, а не конвейер!
  • ls *.txt | % { $files += $_.fullname + $delimiter } - получает список всех текстовых файлов и создает строку со всеми именами файлов, разделенными разделителем
  • application.exe $files - вызывает приложение и передает ему список файлов

Вы даже можете рекурсивно искать шаблон файла, добавив -recurse в ls *.txt чтобы полный код выглядел так:

$delimiter = " "
[string]$files = $nothing ; ls *.txt -recurse | % { $files += $_.fullname + $delimiter } ; application.exe $files

Редактировать:
Чтобы избежать раздражений, ls и dir являются псевдонимами Get-ChildItem а % - псевдонимом ForEach-Object . Я держу свой код с использованием псевдонимов, потому что он короче.

РЕДАКТИРОВАТЬ 2018/04/25:
Еще в 2012 году я был довольно новичком в PowerShell. Конечно, есть более простой способ, хотя он не так прост, как возможность unix/linux по расширению glob:

app.exe $(ls *.txt | % {$_.FullName})

Объяснение:

  • $() сначала вычислит выражение внутри и заменит себя выводом этого выражения (так же, как обратные пометки в bash)
  • ls *.txt получает объекты FileInfo всех файлов, соответствующих глобусу *.txt
  • поскольку PowerShell является объектно-ориентированным, мы должны вывести полное имя каждого объекта FileInfo. Простое присвоение имени атрибуту / свойству в PowerShell выводит его по умолчанию. % { $_.FileName } делает это для нас. % перебирает все элементы, возвращаемые ls и выводит каждый объект FileName.
6

Это даст вам список, а также поместит его в переменную с именем expanded_list . Поместите его в пакетный файл и запустите с myBatchFile name myPattern . Заключите шаблон в кавычки, если он содержит пробелы. Совпадает с файлами, без каталогов. Запуск без параметров соответствует всем.

@echo off
set expanded_list=
for /f "tokens=*" %%F in ('dir /b /a:-d "%~1"') do call set expanded_list=%%expanded_list%% "%%F"

echo expanded_list is: 
echo %expanded_list%

Затем вы можете выполнить команду с помощью my_command_exec %expanded_list%

ПРЕДУПРЕЖДЕНИЕ! Максимальный размер переменной cmd составляет 8191 символ (начиная с XP), поэтому его можно переполнить! Вы не можете рассчитывать на утилиту, чтобы всегда дать вам полный список. С другой стороны, максимальная длина строки cmd также равна 8191, поэтому вы не сможете выполнить ее в любом случае.

3

Это работает в cmd.exe

dir /b *.ext

или же

echo | dir /b *.ext
1

Обратите внимание, это в комментариях к постерам в отдельной ветке user619818 и styfle)

DIR может и позволяет искать во всех подкаталогах файлы, соответствующие определенному типу.

Примечание. Предполагается, что корневым каталогом для проверки того, под какими каталогами находятся все подкаталоги, является «C:\ Моя программа \ Root \», поскольку автор не указал путь, по которому расположены эти каталоги

DIR /B /S "C:\My Program\Root\*.ext"

это даст полные пути к файлам и имена файлов исходных файлов.

если вам нужны только имена файлов, вы должны сделать следующее

FOR /F "Tokens=*" %A IN ('DIR /B /S "C:\My Program\Root\*.ext"') DO @( Echo.%~nxA )

Итак, если вы хотите переместить все эти файлы из «C:\My Program\Root\Sub Directories\*. ext» в «D:\Singlefolder\*. ext», вы просто делаете это:

FOR /F "Tokens=*" %A IN ('DIR /B /S "C:\My Program\Root\*.ext"') DO @( MOVE "%~A" "D:\Singlefolder\%~nxA" /Y )

Надеюсь, что это поможет другим в будущем. :)

1

Это старая версия, но с подсистемой Linux для Windows довольно часто в вашей PATH теперь есть bash. Если это так, то это может помочь вам:

bash -c 'cat *.txt'

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