¿Cómo leer el contenido del archivo en una variable en un archivo por lotes?

161

Este archivo por lotes libera una compilación de TEST a LIVE. Quiero agregar una restricción de verificación en este archivo que garantice que haya un documento de publicación adjunto en una carpeta específica.

"C:\Program Files\Windows Resource Kits\Tools\robocopy.exe" "\\testserver\testapp$"        
"\\liveserver\liveapp$" *.* /E /XA:H /PURGE /XO /XD ".svn" /NDL /NC /NS /NP
del "\\liveserver\liveapp$\web.config"
ren "\\liveserver\liveapp$\web.live.config" web.config

Así que tengo un par de preguntas sobre cómo lograr esto ...

  1. Hay un version.txtarchivo en la \\testserver\testapp$carpeta, y el único contenido de este archivo es el número de compilación (por ejemplo, 45 - para la compilación 45) ¿Cómo leo el contenido del version.txtarchivo en una variable en el archivo por lotes?

  2. ¿Cómo verifico si \\fileserver\myapp\releasedocs\ {build}.docexiste un archivo, usando la variable de la parte 1 en lugar de {build}?

user23048345
fuente

Respuestas:

300

Leer el contenido del archivo en una variable:

for /f "delims=" %%x in (version.txt) do set Build=%%x

o

set /p Build=<version.txt

Ambos actuarán igual con solo una línea en el archivo, para más líneas la forvariante colocará la última línea en la variable, mientras set /pque usará la primera.

Usar la variable, al igual que cualquier otra variable de entorno, es una, después de todo:

%Build%

Entonces, para verificar la existencia:

if exist \\fileserver\myapp\releasedocs\%Build%.doc ...

Aunque bien puede ser que no se permitan rutas UNC allí. No puedo probar esto ahora pero tenlo en cuenta.

Joey
fuente
44
El setmétodo solo lee unos 1024 caracteres, ¿por qué?
Iulian Onofrei
12
Probablemente debido a los límites de un buffer dentro cmd. Es un lenguaje horrible para guiones confiables.
Joey
Lo sé, luché durante horas para reemplazar una cadena en un archivo: |
Iulian Onofrei
16
@IulianOnofrei, set /pllama cmd!ReadBufFromInputcon un búfer asignado en la pila para leer 1023 caracteres de ancho (2046 bytes). Lee 1023 bytes del archivo, suponiendo 1 byte por carácter OEM / ANSI, pero decodifica el archivo utilizando la página de códigos actual, que no es necesariamente OEM / ANSI. El peor de los casos es la página de códigos 65001 y un archivo lleno de caracteres UTF-8 de 4 bytes (por ejemplo, un script antiguo). Obtendrá 255 caracteres, más un carácter parcialmente decodificado almacenado como el personaje de reemplazo, U + FFFD.
Eryk dom
3
@Jan: for /f "usebackq" %%x in ("path with spaces.txt") .... help formenciona esto, por cierto.
Joey
46

Puede leer múltiples variables de un archivo como este:

for /f "delims== tokens=1,2" %%G in (param.txt) do set %%G=%%H

donde param.txt:

PARAM1=value1
PARAM2=value2
...
xnagyg
fuente
1
Esta es la solución perfecta. para responder literalmente el OP, (param.txt)debería ser (version.txt)y debería contenerBuild=45
robotik
Esta es la solución
CÁRCEL
3
%% G fue inesperado en este momento.
John
44
@John: para usar directamente en la línea de comandos, reemplácelos %%Gcon%G
Stephan
32

solo haz:

type version.txt

y se mostrará como si escribiera:

set /p Build=<version.txt
echo %Build%
psrcek
fuente
44
@jeb lo sé, pero todavía estoy agradecido por el comando de tipo porque eso es lo que necesitaba
MSM
Gracias por proporcionar la versión tipo. Funciona exactamente para lo que necesito, accediendo al contenido del archivo que se encuentra en un directorio compartido.
Tastybrownies
22

Para que todas las líneas del archivo se carguen en la variable, se necesita la expansión retardada, así que haga lo siguiente:

SETLOCAL EnableDelayedExpansion

for /f "Tokens=* Delims=" %%x in (version.txt) do set Build=!Build!%%x

Hay un problema con algunos caracteres especiales, aunque especialmente ;, %y!

DPS
fuente
Adjuntando toda la setexpresión entre comillas dobles podría evitar problemas con al menos algunos caracteres especiales: set "Build=!Build!%%x".
aschipfl
9
Mi script solo imprime "echo is ON". ¿Por qué es lote completo de basura?
Trevor Hickey
Funciona para mí sin expansión tardía: set err=(siguiente línea)for /f "delims=" %%x in (err.tmp) do set "err=%err% %%x"
tivnet
2
¿Por qué es lote completo de basura? ...¿por consistencia?
Jan Nielsen