2011-04-28 28 views
12

He siguiente en un archivo por lotes cmd:Cómo reemplazar cadena dentro de un archivo bat con cadena de parámetros de línea de comandos

for /f %%l in (%2) do (for %%f in (%%l) do copy "%%f" %1)) 

nota: este script básicamente hace es leer un archivo de texto que contiene el archivo y coma txt delimitado cuya la ruta viene dada por% 2 (por ejemplo, que contiene c: \ test1 \ file1.cs; d: \ file2.js) y copia los archivos a la carpeta de destino especificada por% 1.

tengo que sustituir la cadena de valor del parámetro %1 de x (que también se pasa al archivo por lotes, por ejemplo %3) con %4 valor que también se pasa como parámetro al archivo por lotes.

ej .:

if %1 = 'test replace x with y' 
%3=x 
%4=y 

lo que la salida debe ser 'prueba sustituye y por y'

¿Cómo puedo lograr esto usando intérprete lotes de Windows CMD?

+0

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

+0

@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

Respuesta

45

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

  1. El retraso de expansión:

  2. En reemplazo de subcadena:

+0

+1, pero ¿por qué demuestras? la evaluación diferida 'perezosa', pero no la (más simple) expansión retrasada? – jeb

+0

@jeb: ¡Gracias por la pregunta!Por alguna razón, no sé por qué, esto no funcionó para mí cuando estaba haciendo pruebas (en Win7): 'set" output =% 1 "; setlocal EnableDelayedExpansion; set "output =! Output:% 3 =% 4!"; endlocal; echo% output% '. Extrañamente, '! Output:% 3 =% 4!' Trabajó en ECHO, pero se negó a tener ningún efecto con SET. La variable simplemente no cambiará. –

+1

Pero está bien, al cambiar la salida var en el bloque 'setlocal', después de' endlocal' la salida var tiene su valor original. No es un problema de Win7 – jeb

0

Si necesita sustituir varios parámetros en una cadena, sólo tiene que utilizar "for/f" para establecer variables con las anteriores sustitución de esta manera:

SET "output1=%1" 
CALL SET output1=%%output1:%3=%4%% 
for /f "tokens=1" %%a in ('echo %output1%') do set output2=%%a 
CALL SET output2=%%output2:%5%6% 
for /f "tokens=1" %%a in ('echo %output2') do set output3=%%a 
3

He intentado debajo de código en Windows 7 archivo de hornada:

SET output=%1 
CALL SET output=%output:unsigned=signed% 
CALL SET output=%output:.apk=-aligned.apk% 

It works!

+0

Pero eso no resuelve la pregunta. La pregunta era sobre reemplazar una cadena con parámetros * desconocidos * en '% 3' y'% 4' – jeb

Cuestiones relacionadas