Comment faire fonctionner SHIFT avec %* dans les fichiers batch
dans mon fichier batch sur Windows XP, je veux utiliser %*
pour étendre à tous les paramètres sauf le premier.
fichier de Test ( foo.chauve-souris ):
@echo off
echo %*
shift
echo %*
appel:
C:> foo a b c d e f
Réelle résultat:
a b c d e f
a b c d e f
Désirée résultat:
a b c d e f
b c d e f
Comment puis-je obtenir le résultat souhaité? Merci!!
6 réponses
ne serait-ce pas merveilleux si CMD.EXE a travaillé comme ça! Malheureusement, il n'est pas une bonne syntaxe qui va faire ce que vous voulez. Le mieux que vous puissiez faire est d'analyser vous-même la ligne de commande et de construire une nouvelle liste d'arguments.
quelque chose comme ça peut marcher.
@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%
mais ce qui précède a des problèmes si un argument contient des caractères spéciaux comme ^
, &
, >
, <
, |
qui ont été évadés au lieu de citer.
la manipulation D'Argument est l'un des nombreux aspects faibles de la programmation Windows batch. Pour à peu près chaque solution, il existe une exception qui cause des problèmes.
ne pensez pas qu'il y ait une façon simple de le faire. Vous pouvez essayer de jouer avec le contournement suivant à la place:
@ECHO OFF
>tmp ECHO(%*
SET /P t=<tmp
SETLOCAL EnableDelayedExpansion
IF DEFINED t SET "t=!t:%1 =!"
ECHO(!t!
exemple:
test.bat 1 2 3=4
sortie:
2 3=4
c'est facile:
setlocal ENABLEDELAYEDEXPANSION
set "_args=%*"
set "_args=!_args:*%1 =!"
echo/%_args%
endlocal
même chose avec les commentaires:
:: 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
exemple:
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
remarques:
- ne fonctionne pas si un argument contient le ! ou & char
- tous les espaces supplémentaires entre les arguments ne seront pas supprimés
j'ai dû faire ça récemment et j'ai trouvé ceci:
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
il utilise la boucle pour sauter N
premiers arguments. Peut être utilisé pour exécuter une commande par argument ou construire une nouvelle liste d'arguments:
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
veuillez noter que le code ci-dessus ajoutera de l'espace de tête aux nouveaux arguments. Il peut être enlevé comme ceci:
une autre façon facile de faire ceci est:
set "_args=%*"
set "_args=%_args:* =%"
echo/%_args%
remarques:
- Ne fonctionne pas si le premier argument (%1) est une "cité" ou "entre guillemets doubles"
- ne fonctionne pas si un argument contient le & char
- tous les espaces supplémentaires entre les arguments ne seront pas supprimés
résumé de tous et corriger tous les problèmes:
set Args=%1
:Parse
shift
set First=%1
if not defined First goto :EndParse
set Args=%Args% %First%
goto :Parse
:EndParse
espaces non supportés entre les arguments: 1 2 3 4
sera 1 2 3 4