배치 파일-명령 줄 인수 수
일부 셸 스크립트를 배치 파일로 변환하기 만하면 찾을 수없는 것 하나가 있습니다. 이것은 명령 줄 인수 수의 단순한 개수입니다.
예. 당신이 가지고 있다면:
myapp foo bar
쉘에서 :
- $ #-> 2
- $ *-> foo 바
- $ 0-> 마이 앱
- $ 1-> foo
- $ 2-> 바
일괄
- ?? -> 2 <---- 무슨 명령?!
- % *-> foo 바
- % 0-> myapp
- % 1-> foo
- % 2-> 막대
그래서 주변을 둘러 보았고 잘못된 지점을 찾고 있거나 장님이지만 전달 된 명령 줄 인수의 수를 계산하는 방법을 찾을 수없는 것 같습니다.
배치 파일에 대한 쉘의 "$ #"과 유사한 명령이 있습니까?
추신. 내가 찾은 가장 가까운 것은 % 1s를 반복하고 'shift'를 사용하는 것이지만 나중에 스크립트에서 % 1, % 2 등을 참조해야하므로 좋지 않습니다.
인터넷 검색을 통해 wikibooks 에서 다음과 같은 결과를 얻을 수 있습니다 .
set argC=0
for %%x in (%*) do Set /A argC+=1
echo %argC%
cmd.exe가 예전 DOS 시대에서 약간 진화 한 것 같습니다. :)
다음과 같은 논리로 여러 인수를 처리하는 경향이 있습니다.
IF "%1"=="" GOTO HAVE_0
IF "%2"=="" GOTO HAVE_1
IF "%3"=="" GOTO HAVE_2
기타
9 개 이상의 인수가있는 경우이 접근 방식에 문제가 있습니다. 여기 에서 찾을 수있는 카운터를 만들기위한 다양한 해킹이 있지만, 이것은 약한 마음을 가진 사람을위한 것이 아닙니다.
:getargc
아래 기능 은 귀하가 찾고있는 것일 수 있습니다.
@echo off
setlocal enableextensions enabledelayedexpansion
call :getargc argc %*
echo Count is %argc%
echo Args are %*
endlocal
goto :eof
:getargc
set getargc_v0=%1
set /a "%getargc_v0% = 0"
:getargc_l0
if not x%2x==xx (
shift
set /a "%getargc_v0% = %getargc_v0% + 1"
goto :getargc_l0
)
set getargc_v0=
goto :eof
기본적으로 목록 (함수에 로컬이므로 시프트가 기본 프로그램의 목록에 다시 영향을주지 않음)을 한 번 반복하여 실행될 때까지 카운트합니다.
또한 함수에 의해 설정 될 반환 변수의 이름을 전달하는 멋진 트릭을 사용합니다.
The main program just illustrates how to call it and echos the arguments afterwards to ensure that they're untouched:
C:\Here> xx.cmd 1 2 3 4 5
Count is 5
Args are 1 2 3 4 5
C:\Here> xx.cmd 1 2 3 4 5 6 7 8 9 10 11
Count is 11
Args are 1 2 3 4 5 6 7 8 9 10 11
C:\Here> xx.cmd 1
Count is 1
Args are 1
C:\Here> xx.cmd
Count is 0
Args are
C:\Here> xx.cmd 1 2 "3 4 5"
Count is 3
Args are 1 2 "3 4 5"
Try this:
SET /A ARGS_COUNT=0
FOR %%A in (%*) DO SET /A ARGS_COUNT+=1
ECHO %ARGS_COUNT%
If the number of arguments should be an exact number (less or equal to 9), then this is a simple way to check it:
if "%2" == "" goto args_count_wrong
if "%3" == "" goto args_count_ok
:args_count_wrong
echo I need exactly two command line arguments
exit /b 1
:args_count_ok
Avoids using either shift
or a for
cycle at the cost of size and readability.
@echo off
setlocal EnableExtensions EnableDelayedExpansion
set /a arg_idx=1
set "curr_arg_value="
:loop1
if !arg_idx! GTR 9 goto :done
set curr_arg_label=%%!arg_idx!
call :get_value curr_arg_value !curr_arg_label!
if defined curr_arg_value (
echo/!curr_arg_label!: !curr_arg_value!
set /a arg_idx+=1
goto :loop1
)
:done
set /a cnt=!arg_idx!-1
echo/argument count: !cnt!
endlocal
goto :eof
:get_value
(
set %1=%2
)
Output:
count_cmdline_args.bat testing more_testing arg3 another_arg
%1: testing
%2: more_testing
%3: arg3
%4: another_arg
argument count: 4
EDIT: The "trick" used here involves:
Constructing a string that represents a currently evaluated command-line argument variable (i.e. "%1", "%2" etc.) using a string that contains a percent character (
%%
) and a counter variablearg_idx
on each loop iteration.Storing that string into a variable
curr_arg_label
.Passing both that string (
!curr_arg_label!
) and a return variable's name (curr_arg_value
) to a primitive subprogramget_value
.In the subprogram its first argument's (
%1
) value is used on the left side of assignment (set
) and its second argument's (%2
) value on the right. However, when the second subprogram's argument is passed it is resolved into value of the main program's command-line argument by the command interpreter. That is, what is passed is not, for example, "%4" but whatever value the fourth command-line argument variable holds ("another_arg" in the sample usage).Then the variable given to the subprogram as return variable (
curr_arg_value
) is tested for being undefined, which would happen if currently evaluated command-line argument is absent. Initially this was a comparison of the return variable's value wrapped in square brackets to empty square brackets (which is the only way I know of testing program or subprogram arguments which may contain quotes and was an overlooked leftover from trial-and-error phase) but was since fixed to how it is now.
The last answer was two years ago now, but I needed a version for more than nine command line arguments. May be another one also does...
@echo off
setlocal
set argc_=1
set arg0_=%0
set argv_=
:_LOOP
set arg_=%1
if defined arg_ (
set arg%argc_%_=%1
set argv_=%argv_% %1
set /a argc_+=1
shift
goto _LOOP
)
::dont count arg0
set /a argc_-=1
echo %argc_% arg(s)
for /L %%i in (0,1,%argc_%) do (
call :_SHOW_ARG arg%%i_ %%arg%%i_%%
)
echo converted to local args
call :_LIST_ARGS %argv_%
exit /b
:_LIST_ARGS
setlocal
set argc_=0
echo arg0=%0
:_LOOP_LIST_ARGS
set arg_=%1
if not defined arg_ exit /b
set /a argc_+=1
call :_SHOW_ARG arg%argc_% %1
shift
goto _LOOP_LIST_ARGS
:_SHOW_ARG
echo %1=%2
exit /b
The solution is the first 19 lines and converts all arguments to variables in a c-like style. All other stuff just probes the result and shows conversion to local args. You can reference arguments by index in any function.
참고URL : https://stackoverflow.com/questions/1291941/batch-files-number-of-command-line-arguments
'Programing' 카테고리의 다른 글
Linux에서는 동일한 번호를 생성하지만 Windows에서는 생성하지 않습니다. (0) | 2020.09.09 |
---|---|
긴 쿼리를 작성하지 않고 모든 GraphQL 유형 필드를 쿼리하는 방법은 무엇입니까? (0) | 2020.09.09 |
정렬 된 사전을 제대로 예쁘게 인쇄하는 방법은 없나요? (0) | 2020.09.09 |
Maven 빌드 플랫폼을 독립적으로 만드는 방법은 무엇입니까? (0) | 2020.09.09 |
쿼리 문자열 및 앵커 해시 태그로 올바른 URL 형성 (0) | 2020.09.09 |