2012-02-20 16 views
30

Nel mio file batch su Windows XP, voglio usare %* per espandere tutti i parametri tranne il primo. file di
prova (foo.bat):Come far funzionare SHIFT con% * nei file batch

@echo off 
echo %* 
shift 
echo %* 

chiamata:

C:\> foo a b c d e f 

Actual risultato:

a b c d e f 
a b c d e f 

desiderata risultato:

a b c d e f 
b c d e f 

Come ottenere il risultato desiderato? Grazie!!

risposta

17

Non sarebbe meraviglioso se CMD.EXE funzionasse in questo modo! Sfortunatamente non c'è una buona sintassi che farà ciò che vuoi. Il meglio che puoi fare è analizzare da solo la riga di comando e creare una nuova lista di argomenti.

Qualcosa del genere può funzionare.

@echo off 
setlocal 
echo %* 
shift 
set "args=" 
:parse 
if "%~1" neq "" (
    set args=%args% %1 
    shift 
    goto :parse 
) 
if defined args set args=%args:~1% 
echo(%args% 

Ma l'ha problemi sopra se un argomento contiene caratteri speciali come ^, &, >, <, | che sono stati sfuggito invece citato.

La gestione degli argomenti è uno dei molti aspetti deboli della programmazione batch di Windows. Per quasi ogni soluzione, esiste un'eccezione che causa problemi.

3

Non pensare che ci sia un modo semplice per farlo. Si potrebbe provare a giocare con la seguente soluzione invece:

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

Esempio:

test.bat 1 2 3=4 

uscita:

2 3=4 
+0

non vedo il beneficio del file temporaneo - 'set t =% *' avrebbe funzionato altrettanto bene. Questa risposta fallirà se% 1 contiene '=' o inizia con '*' o '~'. Inoltre avranno problemi se gli argomenti sono delimitati da ',' o ';' invece di spazi. Meglio rimuovere solo% 1 e lasciare il/i delimitatore/i in posizione. – dbenham

+0

Problema Killer - questa risposta darà una risposta errata se args sono 'A A B'. Potrebbe essere migliorato con 'set t =! T: *% 1 =!' – dbenham

+0

Usando 'set" t =! T: *% 1 =! 'Modifica, questa risposta fallirà se% 1 contiene' = ', ma sta iniziando con '*' o '~' è ok – dbenham

2

thats facile:

setlocal ENABLEDELAYEDEXPANSION 
    set "_args=%*" 
    set "_args=!_args:*%1 =!" 

    echo/%_args% 
endlocal 

Stessa cosa con c OMMENTI:

:: 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 

Esempio:

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 

Osservazione:

  • non funziona se uno degli argomenti contiene l'!o & char
  • non verranno rimossi eventuali spazi aggiuntivi in ​​tra gli argomenti
+0

È necessario rimuovere l'argomento% 1, non il% 0 (che è il nome dello script) –

+0

In effetti, si è corretto. Ho modificato% 0 su% 1 ora. Grazie. – cyberponk

+2

Come scritto, questo è pericolosamente sbagliato, perché il valore per il primo argomento potrebbe essere ripetuto in un successivo argomento e il tuo codice rimuoverà entrambi. Questo potrebbe essere risolto usando '*' per rimuovere tutto attraverso la prima istanza: 'set _args =! _ Args: *% 1 =!'. Altri problemi che non possono essere risolti sono falliti se '% 1' contiene'! 'O' = '. – dbenham

0

Un altro modo semplice per farlo è:

set "_args=%*" 
set "_args=%_args:* =%" 

echo/%_args% 

Osservazione:

  • non funziona se il primo argomento (% 1) è "quotato" o "double quoted"
  • non funziona se uno degli argomenti contiene i & char
  • eventuali spazi aggiuntivi in ​​tra gli argomenti non verranno rimossi
1

ho dovuto fare questo di recente e arrivato fino a questo:

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 

E ' usa il ciclo per saltare sopra i primi argomenti N. Può essere usato per eseguire qualche comando per argomento o costruire nuova lista di argomenti:

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 

prega di notare che il codice di cui sopra si aggiunge lo spazio che porta alle nuove argomentazioni. Può essere rimosso in questo modo: