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

33
demandé sur Thomas Jensen 2012-02-20 18:52:18

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.

20
répondu dbenham 2012-02-20 15:49:12

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
3
répondu Andriy M 2012-02-20 15:50:08

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
3
répondu cyberponk 2016-05-11 17:22:54

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:

1
répondu beatcracker 2017-05-23 10:30:01

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
0
répondu cyberponk 2016-05-11 17:27:45

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

0
répondu Владимир Савин 2018-04-25 03:50:43