Как получить параметры пакетного файла из N-й позиции?
В дополнение к Как передать параметры командной строки в пакетном файле, как получить остальные параметры, указав их точно? Я не хочу использовать SHIFT, потому что я не знаю, сколько параметров там может быть, и хотелось бы избежать их подсчета, если можно.
Например, данный пакетный файл:
@echo off
set par1=%1
set par2=%2
set par3=%3
set therest=%???
echo the script is %0
echo Parameter 1 is %par1%
echo Parameter 2 is %par2%
echo Parameter 3 is %par3%
echo and the rest are %therest%
Запуск mybatch opt1 opt2 opt3 opt4 opt5 ...opt20
даст:
the script is mybatch
Parameter 1 is opt1
Parameter 2 is opt2
Parameter 3 is opt3
and the rest are opt4 opt5 ...opt20
Я знаю, что %*
дает все параметры, но я не делаю первые три (например).
Ответы
Ответ 1
Здесь вы можете сделать это, не используя SHIFT
:
@echo off
for /f "tokens=1-3*" %%a in ("%*") do (
set par1=%%a
set par2=%%b
set par3=%%c
set therest=%%d
)
echo the script is %0
echo Parameter 1 is %par1%
echo Parameter 2 is %par2%
echo Parameter 3 is %par3%
echo and the rest are %therest%
Ответ 2
Но здесь вы знаете, сколько будет. Вы знаете, что у вас будет три. Сдвиг три раза, а остальные параметры находятся в %*
. То есть, когда вы используете shift
, вы изменяете кажущееся значение %*
для представления только тех параметров, которые вы еще не сдвинули.
Ответ 3
В следующем коде используется shift
, но он избегает синтаксического анализа командной строки с помощью for
и позволяет интерпретатору командной строки выполнять это задание (учитывая, что for
не анализирует двойные кавычки должным образом, например, набор аргументов A B" "C
интерпретируется как 3 аргумента A
, B"
, "C
на for
, но как интерпретатор интерпретирует 2 аргумента A
, B" "C
, это предотвращает аргументы цитированного пути, такие как "C:\Program Files\"
from правильное обращение):
@echo off
set "par1=%1" & shift /1
set "par2=%1" & shift /1
set "par3=%1" & shift /1
set therest=
set delim=
:REPEAT
if "%1"=="" goto :UNTIL
set "therest=%therest%%delim%%1"
set "delim= "
shift /1
goto :REPEAT
:UNTIL
echo the script is "%0"
echo Parameter 1 is "%par1%"
echo Parameter 2 is "%par2%"
echo Parameter 3 is "%par3%"
echo and the rest are "%therest%"
rem.the additional double-quotes in the above echoes^
are intended to visualise potential whitespaces
Остальные аргументы в %therest%
могут не выглядеть так, как они были первоначально в отношении разделителей (помните, что интерпретатор командной строки также рассматривает TAB, ,
, ;
, =
как разделители, так и все комбинации), так как все разделители заменяются одним пробелом. Однако, передавая %therest%
в какой-либо другой командный или командный файл, он будет корректно разбираться.
Единственное ограничение, с которым я столкнулся до сих пор, относится к аргументам, содержащим символ каретки ^
. Другие ограничения (связанные с <
, >
, |
, &
, "
) применяются к самому интерпретатору командной строки.
Ответ 4
@ECHO OFF
SET REST=
::# Guess you want 3rd and on.
CALL :SUBPUSH 3 %*
::# ':~1' here is merely to drop leading space.
ECHO REST=%REST:~1%
GOTO :EOF
:SUBPUSH
SET /A LAST=%1-1
SHIFT
::# Let throw the first two away.
FOR /L %%z in (1,1,%LAST%) do (
SHIFT
)
:aloop
SET PAR=%~1
IF "x%PAR%" == "x" (
GOTO :EOF
)
ECHO PAR=%PAR%
SET REST=%REST% "%PAR%"
SHIFT
GOTO aloop
GOTO :EOF
Мне нравится использовать подпрограммы вместо EnableDelayedExpansion
. Выше - извлечение из моей партии обработки файла dir/file. Не говорите, что это не может обрабатывать аргументы с помощью =
, но, по крайней мере, может выполнять цитируемый путь с пробелами и подстановочными знаками.