2009-06-01 11 views
25

duplicado:parámetros de lote: todo lo que después 1%

Aclaración: sabía del enfoque de bucle - esto funcionó incluso antes de que las extensiones de comando; Esperaba algo divertido e indocumentado como% ~ * 1 o lo que sea, como los documentados en http://www.microsoft.com/resources/documentation/windows/xp/all/proddocs/en-us/percent.mspx?mfr=true.


En un archivo por lotes de Windows (con los llamados "las extensiones de comando" en),% 1 es el primer argumento,% 2 es el segundo, etc. *% es todos los argumentos concatenados.

Mi pregunta: ¿hay alguna manera de obtener todo DESPUÉS de% 2, por ejemplo?

No pude encontrar tal cosa, y sería útil para algo en lo que estoy trabajando.

Respuesta

14

No estoy seguro de si hay un comando directo, pero siempre puede usar un simple bucle y desplazamiento para obtener el resultado en una variable. Algo como:

 
@echo off 
set RESTVAR= 
shift 
:loop1 
if "%1"=="" goto after_loop 
set RESTVAR=%RESTVAR% %1 
shift 
goto loop1 

:after_loop 
echo %RESTVAR% 

Avísame si te ayuda!

+0

bien no se dio cuenta de que otras personas ya lo han respondido – Samuel

+0

Sí, pero su respuesta es la más completa y es lo que hice finalmente. – noamtm

+3

Hay un pequeño problema con esta respuesta: 'RESTVAR' contendrá un espacio principal. Aquí hay una versión ligeramente mejor http://stackoverflow.com/a/761658/1488656 – Livven

5

Puede usar SHIFT para esto. Elimina% 1 y desplaza todos los demás argumentos uno más abajo. Este script da salida a todos los argumentos después de 2% (lo que da salida a 3%, 4% ...) hasta que uno de ellos es vacío (por lo que es el último):

@echo off 

SHIFT 
SHIFT 

:loop 
if "%1" == "" goto end 
echo %1 
SHIFT 
goto loop 

:end 

EDIT: ejemplo eliminarse utilizando% * como esto no funciona -% * siempre muestra todos los parámetros

+0

Just like in sh? ¡Estupendo! +1. ¿Sabes cuál es la opción de Powershell? – OscarRyz

+0

Lo sentimos, todavía no hemos usado powershell. – schnaader

1

Basándome en la respuesta de schnaader, creo que esto lo hace si quieres todo después de% 1 concatenado.

@echo off 

SHIFT 

set after1= 

:loop 
if "%1" == "" goto end 
set after1=%after1% %1 
SHIFT 
goto loop 


:end 

echo %after1% 
21

Hay una solución más corta (de una sola línea) la utilización de las capacidades de tokenización de for bucles:

:: all_but_first.bat 
echo all: %* 
for /f "tokens=1,* delims= " %%a in ("%*") do set ALL_BUT_FIRST=%%b 
echo all but first: %ALL_BUT_FIRST% 

salida:

> all_but_first.bat foo bar baz 
all: foo bar baz 
all but first: bar baz 
+1

Para 'todo-pero' n, reemplace 'tokens = 1' con' tokens = n'. Los argumentos restantes seguirán en '%% b' – CJxD

+0

. En algunos casos, es posible que deba usar! ALL_BUT_FIRST! en lugar de% ALL_BUT_FIRST% (por ejemplo, si estás dentro de otro ciclo); vea http://stackoverflow.com/questions/12423238/windows-cmd-set-within-for-loop-is-not-working – FremyCompany

+0

No se olvide de usar 'setlocal enabledelayedexpansion' si está trabajando con'! var! '. –

3

El siguiente trabajo para args con ", =, ' ' (en comparación con @MaxTruxa respuesta)

echo %* 
set _all=%* 
call set _tail=%%_all:*%2=%% 
set _tail=%2%_tail% 
echo %_tail% 

prueba

> get_tail.cmd "first 1" --flag="other options" --verbose 
"first 1" --flag="other options" --verbose 
--flag="other options" --verbose 
+0

Realmente quiero una versión ELI5 de esa línea CALL SET. –

+1

[Uso avanzado: LLAMANDO comandos internos] (https://ss64.com/nt/call.html#advanced). Funciona como 'setLocal EnableDelayedExpansion' +' set _tail =! _ All: *% 2 =! '. –

+0

Fallará en este: get_tail.cmd -s -s arg1 –

1

El siguiente trabajo de argumentos con"= ''. Basado en la respuesta de Dmitry Sokolov. Problema resuelto cuando el segundo arg es el mismo que el primer arg.

@echo off 
echo %* 
set _tail=%* 
call set _tail=%%_tail:*%1=%% 
echo %_tail% 
Cuestiones relacionadas