En primer lugar, tendrá que almacenar %1
en una variable, entonces podrá realizar los reemplazos.
Básicamente, la sintaxis para la sustitución es la siguiente:
%variable:str1=str2%
que significa: 'Cambiar cada str1
en variable
con str2
'.
En su caso, ambos str1
y str2
son parámetros, no cadenas literales. Usando directamente la plantilla anterior, puede terminar con esta expresión:
%variable:%3=%4%
.
Pero eso confundiría al analizador sintáctico, ya que no sabría que primero deben evaluarse %3
y %4
. De hecho, primero trataría de evaluar %variable:%
(y fallar).
Una de las soluciones en este caso podría ser utilizar un método llamado evaluación diferida 'perezosa'. Básicamente, está pasando el comando donde está evaluando una variable al comando CALL. La transformación del comando original a su 'versión CALL' es así:
ECHO %var%
==>CALL ECHO %%var%%
.
Tenga en cuenta el doble %
s. En el momento del análisis, se evalúan a solo %
s. El comando resultante sería analizado nuevamente por CALL, y el efecto final sería el mismo que en el caso del comando original, ECHO %var%
.
Así que funciona igual que el comando original (lo cual es bueno), y lo que estamos ganando aquí es el último momento de la evaluación, me refiero a la evaluación final, cuando la variable se reemplaza por su valor. Al conocer ese efecto, podemos construir nuestra expresión de tal manera que primero se evalúen %3
y %4
, y luego toda la expresión resultante.En concreto, de esta manera:
%%variable:%3=%4%%
Después del primer análisis sintáctico esta expresión se convertiría en algo como esto:
%variable:x=y%
que sería analizada de nuevo, y la salida sería variable
's contenido modificado.
Para una mejor ilustración, aquí es un simple ejemplo de trabajo:
SET "output=%1"
CALL SET output=%%output:%3=%4%%
ECHO %output%
ACTUALIZACIÓN
Hay otro método de hacer lo mismo, lo que probablemente debería haber mencionado en primer lugar.
El shell de comandos de Windows admite una expansión demorada adecuada. Es más simple de usar, pero tiene algunas advertencias.
En primer lugar, cómo usarlo. La sintaxis para la expansión retrasada es !var!
en lugar de %var%
para una expansión inmediata (que sigue siendo válida y se puede usar junto con la sintaxis de expansión retrasada).
Probablemente !var!
no va a funcionar en el script hasta que active la sintaxis con el comando:
SETLOCAL EnableDelayedExpansion
El comando ENDLOCAL
cierra el bloque en el que la sintaxis de expansión retardada es válida e interpretado por el intérprete de comandos.
El script de ejemplo anterior podría reescribirse así:
SET "output=%1"
SETLOCAL EnableDelayedExpansion
SET output=!output:%3=%4!
ECHO !output!
ENDLOCAL
Entonces, ¿cómo funciona esto en caso de que el comando SET output=!output:%3=%4!
:
%3
y %4
se evalúan inmediatamente, es decir, en el análisis sintáctico time - se reemplazan con x
y y
respectivamente;
el comando se convierte en esto: SET output=!output:x=y!
;
el comando está por ejecutarse: se evalúa la expresión !
(x
s se reemplazan por y
s);
el comando se ejecuta - la variable output
se modifica.
Ahora sobre las advertencias. Lo primero que debe recordar es que el !
se convierte en parte de la sintaxis y se consume e interpreta cada vez que se encuentra. Por lo tanto, deberá escaparse donde desee usarlo como literal (como ^!
).
Otra advertencia es el efecto primario de un bloque SETLOCAL/ENDLOCAL.La cuestión es que todos los cambios en las variables de entorno dentro de dicho bloque son, bueno, locales. Al salir del bloque (al ejecutar ENDLOCAL
) la variable se establece en el valor que tenía antes de ingresarlo (antes de ejecutar SETLOCAL
). Esto significa para usted que el valor cambiado de output
solo será válido dentro del bloque SETLOCAL
que tuvo que iniciar para usar la expansión retardada en primer lugar. Posiblemente esto no sea un problema en su caso particular, si solo necesita modificar el valor y luego usarlo de inmediato, pero probablemente deba recordarlo en el futuro.
Nota: Según el comentario Jeb 's, puede guardar el valor modificado y dejar el bloque SETLOCAL usando este truco:
ENDLOCAL & SET "output=%output%"
El operador &
simplemente delimita los comandos cuando se colocan en el misma línea. Se ejecutan uno después del otro, en el mismo orden en que se especifican. El problema es que, al momento de analizar la línea, el bloque SETLOCAL no se ha dejado todavía, por lo que %output%
evalúa el valor modificado, que sigue siendo válido. Pero la asignación se ejecuta en realidad después deENDLOCAL
, es decir, después de abandonar el bloque. De modo que está almacenando efectivamente el valor modificado después de abandonar el bloque, preservando así los cambios.
Más información (Gracias, Jeb!):
El retraso de expansión:
En reemplazo de subcadena:
Es difícil analizar su solicitud. ¿Por qué no puedes usar% 4 las dos veces que lo necesitas e ignoras% 3? ...... Muéstranos un poco más de detalles sobre lo que tienes y deberíamos poder ayudarte. Buena suerte. – shellter
@shelter, el problema es% 3 y% 4 es diferente, este lote es invocado por el script MSBuild externo. la cadena de reemplazo y las cadenas a ser reemplazadas son diferentes, por ejemplo: podría necesitar reemplazar "x" ocurrencias en FIND STRING (por ejemplo, "test replace xxx") con "y" Thanks .... – DSharper