Как да използвате повече от 9 аргумента, когато извиквате етикет в пакетен скрипт на CMD?

Бих искал да знам как да извикам повече от 9 аргумента в пакетен скрипт, когато извиквам етикет. Например, следното показва, че имам 12 присвоени аргумента заедно с опит да повторя всички тях.

CALL:LABEL "one" "two" "three" "four" "five" "six" "seven" "eight" "nine" "ten" "eleven" "twelve"
PAUSE
GOTO:EOF


:LABEL
echo %1
echo %2
echo %3
echo %4
echo %5
echo %6
echo %7
echo %8
echo %9
echo %10
echo %11
echo %12

Резултатът за %10 %11 и %12 завършва като one0 one1 one2. Опитах да използвам къдрави скоби, скоби, кавички, единични кавички около числата без никакъв успех.


person Anthony Miller    schedule 30.11.2011    source източник
comment
Бих искал да добавя, че SHIFT позволява превключвател /N да се използва заедно с него, за да изберете от кой аргумент да започнете. Например, ако сте използвали SHIFT за достъп до 10-ти аргумент, за да получите отново достъп до аргумент 0 (вашият абсолютен път към текущо изпълнявания пакетен скрипт), можете да използвате SHIFT /N 0, който ви връща обратно към вашите оригинални аргументи 0-9.   -  person Anthony Miller    schedule 30.11.2011
comment
Възможен дубликат на Как да предам повече от 9 параметъра към пакета файл   -  person Jack Kasbrack    schedule 09.11.2018


Отговори (5)


Използвайте shift команда, ако искате да работите с още 9 параметъра.< br> (всъщност повече от 10 параметъра, ако броите параметъра %0)

Можете [...] да използвате командата shift, за да създадете пакетен файл, който може да приеме повече от 10 пакетни параметъра. Ако зададете повече от 10 параметъра в командния ред, тези, които се появяват след десетия (%9), ще бъдат преместени един по един в %9.

Можете или да използвате цикъл, да съхраните променливите преди преместване или да го направите бързо по този начин:

@echo off
CALL:LABEL "one" "two" "three" "four" "five" "six" "seven" "eight" "nine" "ten" "eleven" "twelve"
PAUSE
GOTO:EOF

:LABEL
:: print arguments 1-9
echo %1
echo %2
echo %3
echo %4
echo %5
echo %6
echo %7
echo %8
echo %9

:: print arguments 10-11
shift
shift 
echo %8
echo %9

:: print argument 13
shift
echo %9

Можете да замените командите за преместване с цикъл, в случай че имате много аргументи. Следният for цикъл се изпълнява shift девет пъти, така че %1 ще бъде десетият аргумент.

@for /L %%i in (0,1,8) do shift
person kapex    schedule 30.11.2011
comment
но в този случай %7,%8,%9 се отнасят за по-старите стойности, а не за десет, единадесет и т.н...... - person iAmLearning; 11.02.2014
comment
моля, вижте stackoverflow.com/questions/21694861/ - person iAmLearning; 11.02.2014

Ако приемем, че използваме скорошна версия на CMD тук, аз съм доста шокиран да открия, че никой не е публикувал следното, което позволява произволен брой аргументи да бъдат обработени лесно, без изобщо да се използва тромавата команда shift:

rem test.bat
call :subr %*
exit /b

:subr
for %%A in (%*) do (
    echo %%A
)
exit /b

Можете също така да изпълнявате същата техника направо в "main".

По този начин вие не изяждате аргументите си, докато ги обработвате, и няма нужда от shift, което означава, че можете последователно да преминавате през списъка с аргументи повече от веднъж, ако имате сложни опции за извикване и това се случи да направи вашия скрипт по-проста логика.

Очевидно, ако do премине повече от веднъж, това увеличава изчислителната сложност в замяна на четливост, но нито Bash, нито CMD наистина са създадени за голяма скорост (доколкото някога съм чувал), така че има малко смисъл да се опитвате да оптимизирате, като направите настройка всичко в едно, ако приемем, че n е по-малко от 100 или нещо такова.

Някои примерни резултати:

C:\tmp>test.bat one two three four five six seven eight nine ten eleven
one
two
three
four
five
six
seven
eight
nine
ten
eleven

редактиране – В случай, че някой обработва аргументи срещу друг списък и част от работата е вложена, важно е да се използва посредник CALL, който да позволи на текущия обработван аргумент да бъде прехвърлен във вътрешния цикъл ; простото правене на set intermediary=%%OUTER изглежда просто задава intermediary на празен низ, така че е следващото най-лесно да направите това:

setlocal enabledelayedexpansion
rem ^ in my experience, it's always a good idea to set this if for-loops are involved
for /f %%L in (file.txt) do (
    call :inner %%L
)
exit /b

:inner
for %%A in (%*) do (
    if %%A EQU %~1 call dosomething.bat %~1        
)
exit /b

редактиране 2 - Освен това, ако по някаква причина искате да добавите подхода shift към микса тук – може би като се опитате да предадете всички аргументи, различни от 1-ви, към подпрограма, като използвате shift и след това използвате call :subroutine %* – имайте предвид, че няма да работи, защото %* всъщност ви дава всички оригинални аргументи в ред, без да знае каквото и да е преместване, което сте направили.
Жалко е, защото няма собствен синтаксис (за който знам), който може да групира всички аргументи след определен, както може да се очаква да направи %3*.

person Community    schedule 27.04.2015

Това е друг начин за използване на командата shift.

Имайте предвид, че в този случай можете да използвате променлив брой параметри.

@ECHO OFF
CALL:LABEL "one" "two" "three" "four" "five" "six" "seven" "eight" "nine" "ten" "eleven" "twelve"
PAUSE
GOTO:EOF

:LABEL
echo %1
shift
if not [%1]==[] GOTO LABEL
person kkk    schedule 07.11.2013

Не можете да имате повече от 10 (0 до 9) достъпни аргумента (%0 е самият пакетен файл) в пакетен файл. Използването на командата shift обаче ще ви позволи да "изместите наляво" вашите аргументи и да получите достъп до тези аргументи след 9-ия. Ако го направите три пъти, трябва да завършите с %7, %8 и %9, съдържащи "десет", "единадесет" и "дванадесет".

person Laf    schedule 30.11.2011

Просто хвърлям шапката си на ринга, ако това помага на някого

Set a=%1 & Set b=%2 & Set c=%3 & Set d=%4 & Set e=%5 & Set f=%6 & Set g=%7 & Set h=%8 & Set i=%9
Shift & Shift & Shift & Shift & Shift & Shift & Shift & Shift & Shift
Set j=%1 & Set k=%2 & Set l=%3 & Set m=%4 & Set n=%5 & Set o=%6 & Set p=%7 & Set q=%8 & Set r=%9
Shift & Shift & Shift & Shift & Shift & Shift & Shift & Shift & Shift
Set s=%1 & Set t=%2 & Set u=%3 & Set v=%4 & Set w=%5 & Set x=%6 & Set y=%7 & Set z=%8

Просто поставям това в горната част на .bat или подпрограмата, която ще използва >9 аргумента, след което можете да използвате %a% до %z% вместо %1 до несъществуващия %26.

Доста е грозен, първоначално го имах един ред à la

Set a=%1 & Shift & Set b=%1 & Shift &...

По този начин той е само на един ред и се скрива зад ръба на редактора доста бързо, но очевидно Shift няма да влезе в сила до следващия истински ред; всички променливи бяха зададени на първия параметър.

Ако се чудите защо да правите това вместо циклите, освен ако някой не ми покаже, че можете да създадете нещо като карта или масив, трябваше да използвам променливите в едноредова команда, а не echo (или да направя каквото и да е) с тях на време:

::example; concatenate a bunch of files
Set output=%1
Shift
<insert above behemoth>
type %a% %b% %c% %d% %e% %f% 2>NUL > %output%

По дяволите, това беше много по-лесно в bash

cat ${@:2} > "$1"
person Hashbrown    schedule 15.07.2016