Вопрос или проблема
Я уже знаю, что %*
разворачивается в полный список параметров, переданных скрипту.
Я также знаю, что для специфических параметров (т.е. %1
) существуют расширения, которые извлекают определенные части этих параметров (например: %~dp1
извлекает букву диска и путь первого параметра, а %~nx1
извлекает имя файла и его расширение).
Как мне применить эти расширения к списку, возвращаемому %*
? Я ожидал, что %~nx*
будет работать, но, похоже, это невалидный синтаксис.
Мое текущее решение — перенаправить список в файл, использовать PowerShell для удаления директорий из этого файла, а затем прочитать модифицированное содержимое (см. ниже). Очевидно, это запутано и неэффективно, поэтому я ищу более простое решение.
echo %*>files.txt
set p=%~dp0
powershell -c "(Get-Content 'files.txt').replace('%p%','') | Set-Content 'files.txt'"
set /p files=<files.txt
Лучшее решение (на основе комментариев): использовать call set
для применения замены строк с переменной пути:
set p=%~dp0
set files=%*
call set "files=%%files:%p%=%%"
Ответ или решение
Для того чтобы применить расширения параметров к списку командных параметров, возвращаемых с помощью %*
, необходимо понимать правила работы командной строки Windows (или CMD). Необходимо отметить, что %*
представляет собой все параметры, переданные вашему скрипту, и не поддерживает прямое применение расширений, таких как %~nx*
, поскольку синтаксис %~nX
и подобные ему достигают только отдельных параметров (например, %1
, %2
, и так далее).
Проблема с использованием %*
Когда вы пытаетесь использовать %~nx*
, возникает ошибка, потому что система не распознает это выражение как допустимое. Это связано с тем, что прежде чем применить любые расширения к параметрам, вам следует разбить их на отдельные элементы.
Решение проблемы
Вместо прямого применения расширений к %*
, вам нужно обрабатывать каждый параметр отдельно. Это можно сделать с помощью цикла for
. Вот как это можно реализовать:
@echo off
setlocal enabledelayedexpansion
set files=
for %%A in (%*) do (
set "filename=%%~nxA"
set "files=!files! !filename!"
)
echo !files!
Пояснение кода
-
setlocal enabledelayedexpansion
: Эта команда позволяет использовать расширение переменных внутри цикла, что особенно важно для правильной работы с переменнойfiles
. -
*Цикл `for %%A in (%)`**: Этот цикл проходит по каждому параметру, переданному скрипту.
-
set "filename=%%~nxA"
: Используя%~nxA
, вы извлекаете только имя файла и его расширение. -
set "files=!files! !filename!"
: Здесь происходит накопление результатов в переменнойfiles
, где!
используется для работы с переменными при расширенной рассылке. -
echo !files!
: Наконец, вы выводите итоговую строку.
Заключение
С помощью приведенного выше подхода вы сможете легко обрабатывать списки параметров, переданных в скрипт, и применять к ним необходимые расширения. Это простое, но эффективное решение позволяет избежать сложных обходных путей, таких как работа с файлами или PowerShell, и делает ваш код более чистым и производительным.