Jak wykryć liczbę parametrów w pliku wsadowym i przejść przez nie?

6

Czy istnieje prosty sposób na wykrycie liczby parametrów przekazanych jako argumenty do pliku wsadowego, a następnie wykorzystanie ich for /Ldo zapętlenia?

builder_247
źródło

Odpowiedzi:

6

Jak wykryć liczbę parametrów w pliku wsadowym i przejść przez nie?

%* w skrypcie wsadowym odnosi się do wszystkich argumentów (np.% 1% 2% 3% 4% 5 ...% 255)

Można użyć %*do pobrania wszystkich argumentów wiersza poleceń do pliku wsadowego.

Aby policzyć argumenty i pętli z for /Lzobaczyć StackOverflow odpowiedź Batch-Script - iterację argumenty przez aacini :

@echo off
setlocal enabledelayedexpansion

set argCount=0
for %%x in (%*) do (
   set /A argCount+=1
   set "argVec[!argCount!]=%%~x"
)

echo Number of processed arguments: %argCount%

for /L %%i in (1,1,%argCount%) do echo %%i- "!argVec[%%i]!"

Dalsza lektura

DavidPostill
źródło
Czy w pierwszym zdaniu miałeś na myśli% *, a nie $ *?
RockPaperLizard
@RockPaperLizard Tak, literówka, dzięki i poprawiona odpowiedź.
DavidPostill
Nie ma za co. Możesz zmienić „for / l” (mała litera el) na „for / L” w drugim zdaniu, aby pasowało do „for / L” w twoim przykładzie. Jak zapewne zauważyłeś, „ukośnik w przód małe litery el” w wielu czcionkach przypomina „ukośnik w przód numer jeden”. W twoim przykładzie użyto dużej litery el, co czyni to bardzo jasnym.
RockPaperLizard
1

Ogólnie @DavidPostill ma poprawną odpowiedź. Nie zobaczy /?jednak przełączników (i prawdopodobnie kilku innych). Jeśli chcesz je zobaczyć, możesz użyć: for %%x in ("%*") do (zamiast for %%x in (%*) do (. Problem polega na tym, że ta wersja nie widzi niczego w cudzysłowie. Jeśli chcesz wersję, która może obsługiwać obie te funkcje, oto zdecydowanie mniej prosta odpowiedź:

@set @junk=1 /*
@ECHO OFF
:: Do not changes the above two lines. They are required in order to make the 
:: JScript below work.

:: In order to get the parameter count from WSH we will call this script 
:: three times in three different ways. The first time, it'll run the code in this
:: section just as any normal BATCH script would. At the end of this section, it'll 
:: call cscript.exe in order to run the JScript portion below.

:: The final call will be the same call as was originally requested but with the 
:: difference of the first parameter being the word redux (if that is a possible 
:: valid value for your script then you'll want to change it here and in the 
:: JScript below as well).
IF "%1" == "redux" @GOTO :CLOSINGTIME

:: The next step passes this script to get the WSH command line executable for 
:: further processing.
cscript //nologo //E:jscript %~f0 %*

:: Exit the initial call to this script.
GOTO:EOF */

// We are now in the second iteration of the call. Here we are using JScript 
// instead of batch because WSH is much better at counting it's parameters.

var args=WScript.Arguments, 
    sh=WScript.CreateObject("WScript.Shell"),
    cmd="%comspec% /k " + WScript.ScriptFullName + ' redux ' + args.length;

for(var i=0, j=args.length; i<j; i++)
    cmd+=' "' + args(i) + '"';

// sh.Popup("The generated command line is:\n  "+cmd);

var exec=sh.Exec(cmd);
while(!exec.StdOut.AtEndOfStream)
  WScript.Echo(exec.StdOut.ReadLine());

// Leave the script now. Remember that the entire script needs to be parsable by
// WSH so be sure that anything after this line is in the comment below.
WScript.Quit(0);

/* This line is here to hide the rest of the file from WSH.
========================================================================

:CLOSINGTIME

:: Now we've called this script 3 times (once manually and now twice more just
:: to get back here knowing the correct argument count. We've added that value
:: to the command line so lets remove that cruft before we call this done.

:: Remove the static, redux, parameter
SHIFT

:: Save the argument count.
SET ARGC=%1

:: Remove ARGC parameter
SHIFT

:: Now you are ready to use your batch code. The variable %ARGC% contains the
:: argument count of the original call.


:: ******************************
:: ** START OF YOUR BATCH CODE **
:: ******************************

ECHO Fancy JScript count: %ARGC%
ECHO.

:: ****************************
:: ** END OF YOUR BATCH CODE **
:: ****************************

:: This is needed in order to let the JScript portion know that output has ended.
EXIT

:: ========================================================================
:: This line will hide everything in your second BATCH portion from WSH. */

Niestety, nie jest to również idealna odpowiedź ze względu na sposób, w jaki musieliśmy wykonać plik z poziomu WSH, StdErr i StdOut są zepsute dla końcowego skryptu. Możesz naprawić StdErr w niektórych sytuacjach, używając 2&>1na końcu drugiego wywołania wsadowego: var exec=sh.Exec(cmd+" 2&>1");StdIn będzie musiał być traktowany jako specjalny przypadek dla każdego skryptu.

krowe2
źródło