Есть ли способ указать последние n параметров в пакетном файле?
В следующем примере я хочу вызвать дочерний пакетный файл из родительского пакетного файла и передать все остальные параметры дочернему.
C:\> parent.cmd child1 foo bar
C:\> parent.cmd child2 baz zoop
C:\> parent.cmd child3 a b c d e f g h i j k l m n o p q r s t u v w x y z
Внутри parent.cmd мне нужно удалить% 1 из списка параметров и передать оставшиеся параметры дочернему элементу script.
set CMD=%1
%CMD% <WHAT DO I PUT HERE>
Я исследовал использование SHIFT с% *, но это не работает. Хотя SHIFT будет перемещать позиционные параметры вниз на 1,% * по-прежнему относится к исходным параметрам.
У кого-нибудь есть идеи? Должен ли я просто отказаться и установить Linux?
Ответы
Ответ 1
%*
, к сожалению, всегда будет распространяться на все исходные параметры. Но вы можете использовать следующий фрагмент кода для создания переменной, содержащей все, кроме первого параметра:
rem throw the first parameter away
shift
set params=%1
:loop
shift
if [%1]==[] goto afterloop
set params=%params% %1
goto loop
:afterloop
Я думаю, что это можно сделать короче, хотя... Я не пишу такого рода вещи очень часто:)
Должен работать, однако.
Ответ 2
Здесь однострочный подход с использованием команды "для"...
for /f "usebackq tokens=1*" %%i in (`echo %*`) DO @ set params=%%j
Эта команда назначает 1-й параметр "i", а остальная часть (обозначается "*" ) назначается "j", которая затем используется для установки переменной "params".
Ответ 3
строка
%CMD% <WHAT DO I PUT HERE>
должно быть изменено на:
(
SETLOCAL ENABLEDELAYEDEXPANSION
SET Skip=1
FOR %%I IN (%*) DO IF !Skip! LEQ 0 (
SET params=!params! %%I
) ELSE SET /A Skip-=1
)
(
ENDLOCAL
SET params=%params%
)
%CMD% %params%
конечно, вы можете установить Skip на любое количество аргументов.
Ответ 4
Вы можете просто сделать это:
%*
Если это единственное в строке, то это расширяется до того, что будет выполняться первый параметр, а все остальные параметры переданы ему.:)
Ответ 5
Другой способ (почти такой же, как Alxander Bird) без выполнения ECHO в подоболочке:
FOR /F "usebackq tokens=1*" %%I IN ('%*') DO SET params=%%J
так, строка
%CMD% <WHAT DO I PUT HERE>
будет выглядеть так:
FOR /F "usebackq tokens=1*" %%I IN ('%*') DO %CMD% %%J
проблема заключается в том, что если параметры включают цитируемые stings с пробелами внутри, cmd.exe будет правильно их анализировать для использования в качестве пронумерованных аргументов (% 1), но FOR будет игнорировать кавычки. В этом конкретном случае это вредит, если первый параметр содержит пробел или больше, что вполне возможно, учитывая, что% CMD% может быть, например, "C:\Program Files\Internet Explorer\iexplore.exe".
Итак, вот еще один ответ.
Ответ 6
Хотя на самом деле решение "для" превосходит в самых разных обстоятельствах, для чего-то простого я часто просто сохраняю и переношу другие аргументы, а затем использую %*
как обычно (практически такая же стратегия часто работает для $*
или [email protected]
в {,ba,da,k,*}sh
):
Пример:
:: run_and_time_me.cmd - run a command with the arguments passed, while also piping
:: the output through a second passed-in executable
@echo off
set run_me=%1
set pipe_to_me=%2
shift
shift
:: or
:: set run_me=%1
:: shift
:: set pipe_to_me=%1
:: shift
%run_me% %* | %pipe_to_me%
Во всяком случае, я видел, что вопрос был долгим, но подумал, что я загляжу в свои два цента, потому что это было то, чего я не видел, и потому что это был тот ответ, который мне нужен, когда я, наконец, через несколько лет назад... и пошел "о... дух".:)
Ответ 7
Я столкнулся с этим вопросом, пока сталкивался с аналогичной проблемой, но решил это с помощью другого подхода.
Вместо повторного создания строки ввода с использованием цикла (как в ответе @Joey) я просто удалил первый параметр из входной строки.
set _input=%*
set params=!_input:%1 =!
call OTHER_BATCH_FILE.cmd %params%
Конечно, это предполагает, что все параметры разные.