How to make SHIFT work with %* in batch files

后端 未结 7 1804
独厮守ぢ
独厮守ぢ 2020-12-24 11:38

In my batch file on Windows XP, I want to use %* to expand to all parameters except the first.
Test file (foo.bat):



        
相关标签:
7条回答
  • 2020-12-24 11:59

    I had to do this recently and came up with this:

    setlocal EnableDelayedExpansion
    
    rem Number of arguments to skip
    set skip=1
    
    for %%a in (%*) do (
      if not !position! lss !skip! (
        echo Argument: '%%a'
      ) else (
        set /a "position=!position!+1"
      )
    )
    
    endlocal
    

    It uses loop to skip over N first arguments. Can be used to execute some command per argument or build new argument list:

    setlocal EnableDelayedExpansion
    
    rem Number of arguments to skip
    set skip=1
    
    for %%a in (%*) do (
      if not !position! lss !skip! (
        set args=!args! %%a
      ) else (
        set /a "position=!position!+1"
      )
    )
    
    echo %args%
    
    endlocal
    

    Please note that the code above will add leading space to the new arguments. It can be removed like this:

    • How to remove trailing and leading whitespace for user-provided input in a batch file?
    0 讨论(0)
  • 2020-12-24 12:05

    That´s easy:

    setlocal ENABLEDELAYEDEXPANSION
      set "_args=%*"
      set "_args=!_args:*%1 =!"
    
      echo/%_args%
    endlocal
    

    Same thing with comments:

    :: Enable use of ! operator for variables (! works as % after % has been processed)
    setlocal ENABLEDELAYEDEXPANSION
      set "_args=%*"
      :: Remove %1 from %*
      set "_args=!_args:*%1 =!"
      :: The %_args% must be used here, before 'endlocal', as it is a local variable
      echo/%_args%
    endlocal
    

    Example:

    lets say %* is "1 2 3 4":
    
    setlocal ENABLEDELAYEDEXPANSION
      set "_args=%*"             --> _args=1 2 3 4
      set "_args=!_args:*%1 =!"  --> _args=2 3 4
    
      echo/%_args%
    endlocal
    

    Remarks:

    • Does not work if any argument contains the ! or & char
    • Any extra spaces in between arguments will NOT be removed
    • %_args% must be used before endlocal, because it is a local variable
    • If no arguments entered, %_args% returns * =
    • Does not shift if only 1 argument entered
    0 讨论(0)
  • 2020-12-24 12:07

    Resume of all and fix all problems:

    set Args=%1
    :Parse
    shift
    set First=%1
    if not defined First goto :EndParse
      set Args=%Args% %First%
      goto :Parse
    :EndParse
    

    Unsupport spaces between arguments: 1 2 3 4 will be 1 2 3 4

    0 讨论(0)
  • 2020-12-24 12:09

    Don't think there's a simple way to do so. You could try playing with the following workaround instead:

    @ECHO OFF
    >tmp ECHO(%*
    SET /P t=<tmp
    SETLOCAL EnableDelayedExpansion
    IF DEFINED t SET "t=!t:%1 =!"
    ECHO(!t!
    

    Example:

    test.bat 1 2 3=4
    

    Output:

    2 3=4
    
    0 讨论(0)
  • 2020-12-24 12:09

    Yet another obnoxious shortcoming of DOS/Windows batch programming...

    Not sure if this is actually better than some of the other answers here but thought I'd share something that seems to be working for me. This solution uses FOR loops rather than goto, and is contained in a reusable batch script.

    Separate batch script, "shiftn.bat":

    @echo off
    setlocal EnableDelayedExpansion
    set SHIFTN=%1
    FOR %%i IN (%*) DO IF !SHIFTN! GEQ 0 ( set /a SHIFTN=!SHIFTN! - 1 ) ELSE ( set SHIFTEDARGS=!SHIFTEDARGS! %%i ) 
    IF "%SHIFTEDARGS%" NEQ "" echo %SHIFTEDARGS:~1%
    

    How to use shiftn.bat in another batch script; in this example getting all arguments following the first (skipped) arg:

    FOR /f "usebackq delims=" %%i IN (`call shiftn.bat 1 %*`) DO set SHIFTEDARGS=%%i 
    

    Perhaps someone else can make use of some aspects of this solution (or offer suggestions for improvement).

    0 讨论(0)
  • 2020-12-24 12:12

    Another easy way of doing this is:

    set "_args=%*"
    set "_args=%_args:* =%"
    
    echo/%_args%
    

    Remarks:

    • Does not work if first argument (%1) is 'quoted' or "double quoted"
    • Does not work if any argument contains the & char
    • Any extra spaces in between arguments will NOT be removed
    0 讨论(0)
提交回复
热议问题