batch file - escape - Ignorar el signo de porcentaje en el archivo por lotes
escape 2 (5)
Creo que tengo una solución parcial funcionando. Si solo busca transferir archivos que tienen la cadena "% 20" en su nombre y no busca una solución más amplia, puede hacer que un segundo archivo por lotes llame al primero con %% 2 como el segundo parámetro. De esta forma, cuando su programa intente buscar el segundo parámetro cuando llegue al% 2 en el nombre del texto, reemplazará el% 2 con un% 2 escapado, sin cambiar el nombre del archivo.
¡Espero que esto funcione!
Tengo un archivo por lotes que mueve los archivos de una carpeta a otra. El archivo por lotes es generado por otro proceso.
Algunos de los archivos que necesito mover tienen la cadena "% 20" en ellos:
move /y "//myserver/myfolder/file%20name.txt" "//myserver/otherfolder"
Esto falla al intentar encontrar un archivo con el nombre:
//myserver/myfolder/file0name.txt
¿Hay alguna forma de ignorar %
? No puedo alterar el archivo generado para escapar de esto, como duplicar los signos de porcentaje ( %%
), escapar con /
o ^
(cursivo), etc.
Debería poder usar un símbolo de intercalación (^) para escapar de un signo de porcentaje .
Nota del editor: el enlace está muerto ahora; de cualquier forma: es el propio %
que escapa %
, pero solo en los archivos por lotes, no en el símbolo del sistema; ^
nunca escapa %
, pero en el símbolo del sistema puede usarse indirectamente para evitar la expansión de variables, solo en cadenas sin comillas .
La razón por la que %2
está desapareciendo es que el archivo por lotes está sustituyendo el segundo argumento pasado, y parece que no tiene un segundo argumento. Una forma de evitar esto sería probar foo.bat ^%1 ^%2...
modo que cuando se encuentre un %2
en un comando, en realidad se sustituya por un literal %2
.
En los archivos por lotes, el signo de porcentaje puede "escaparse" utilizando un signo de porcentaje doble (%%). De esta forma, se usará un solo signo de porcentaje dentro de la línea de comando. de http://www.robvanderwoude.com/escapechars.php
Necesita usar %%
en este caso. Normalmente, usar ^
(cursivo) funcionaría, pero para %
signos, debe duplicar.
En el caso de %%1
o %%i
o echo.%%~dp1
, porque %
indica entrada desde un comando o desde una variable (cuando está rodeado con %
; %variable%
)
Para lograr lo que necesita:
move /y "//myserver/myfolder/file%%20name.txt" "//myserver/otherfolder"
¡Espero que esto ayude!
El título de la pregunta es muy genérico , lo que inevitablemente atrae a muchos lectores que buscan una solución genérica.
Por el contrario, el problema del OP es exótico : la necesidad de tratar con un archivo por lotes autogenerado que está mal formado y no se puede modificar : los signos de %
no se escapan correctamente en él.
La respuesta aceptada proporciona una solución inteligente al problema específico , y exótico, pero crea confusión con respecto a la pregunta genérica .
Si nos enfocamos en la pregunta genérica :
¿Cómo se usa %
como carácter literal en un archivo por lotes / en la línea de comando?
Dentro de un archivo por lotes , siempre escape
%
como%%
, ya sea en cadenas sin comillas o no; los siguientes rendimientosMy %USERNAME% is jdoe
, por ejemplo:echo My %%USERNAME%% is %USERNAME% echo "My %%USERNAME%% is %USERNAME%"
En la línea de comandos (interactivamente), así como al usar las funciones de invocación de shell de los lenguajes de scripting , el comportamiento difiere fundamentalmente de los archivos por lotes internos : técnicamente, no se puede escapar
%
y no existe una solución única que funcione en todas las situaciones :En cadenas sin comillas , puede usar el truco "
^
name-disrupter" : para simplificar, coloque un^
antes de cada%
char , pero tenga en cuenta que aunque técnicamente no está escapando%
esa manera (consulte más abajo para obtener más información); por ejemplo, lo siguiente arroja algo así comoMy %USERNAME% is jdoe
:echo My ^%USERNAME^% is %USERNAME%
En cadenas de comillas dobles , no puede escapar
%
en absoluto , pero hay soluciones :Puede usar cadenas sin comillas como se indicó anteriormente, lo que le exige además que elimine todos los demás metacaracteres del shell, lo cual es engorroso; estos metacaracteres son:
<space> & | < > "
<space> & | < > "
Alternativamente, si el programa objetivo lo admite ( debería funcionar con la mayoría de los ejecutables binarios , pero no con los archivos por lotes ), puede representar
%
chars. como"%"
; p.ej:echo "My "%"USERNAME"%" is %USERNAME%"
Desde los lenguajes de scripting , si sabe que está llamando a un ejecutable binario , puede evitar todo el problema al renunciar a las funciones invocadas por el shell en favor de las variantes "sin shell" , como usar
execFileSync
lugar deexecSync
en Node.js.
Información de fondo opcional para el uso de la línea de comando (interactiva):
Consejo del sombrero para pedir su ayuda con esta sección.
En la línea de comando (interactivamente), el %
técnicamente no se puede escapar en absoluto ; Mientras ^
es generalmente el carácter de escape de cmd.exe
, no se aplica a %
.
Como se indicó, no existe una solución para cadenas de comillas dobles , pero existen soluciones para las cadenas sin comillas :
La razón por la que funciona el truco " ^
name-disrupter" (algo así como ^%USERNAME^%
) es:
"Interrumpe" el nombre de la variable ; es decir, en el ejemplo anterior
cmd.exe
busca una variable llamadaUSERNAME^
, que (afortunadamente) no existe.En la línea de comandos, a diferencia de los archivos por lotes, las referencias a variables indefinidas se conservan tal cual .
Técnicamente, un único ^
dentro del nombre de la variable, en cualquier lugar dentro de él, siempre que no esté junto a otro ^
- es suficiente, por lo que %USERNAME^%
, por ejemplo, sería suficiente, pero sugiero adoptar la convención de colocar metódicamente ^
antes de cada %
para simplificar , porque también funciona para casos como up 20^%
, donde la interrupción ni siquiera es necesaria, pero es benigno, por lo que puede aplicarlo metódicamente , sin tener que pensar en los detalles de la cadena de entrada.
A ^
antes de un %
apertura , aunque no es necesario, es benigno, porque ^
escapa al siguiente carácter, ya sea que ese personaje necesite escapar -o, en este caso, se puede escapar- o no. El efecto neto es que dichas instancias ^
se eliminan en última instancia de cadenas sin comillas .
Advertencia en gran parte hipotética : ^
es en realidad un carácter legal en los nombres de variables (ver el ejemplo de jeb en los comentarios); si su nombre de variable termina con ^
, simplemente coloque el "perturbador" ^
algún otro lugar en el nombre de la variable, siempre que no esté directamente al lado de otro ^
(ya que eso provocaría que ^
aparezca en la cadena resultante).
Dicho esto, en el caso (muy poco probable) de que su variable tenga un nombre como ^b^
, no tiene suerte.