2012-05-15 6 views
5

Tengo un archivo denominado archivo.txt que contiene:archivo de texto de múltiples líneas, cómo poner en una variable de entorno

 this is line one^
    this is line two^
    this is the last line 

cómo puedo poner esto en una var env?

que puedo hacer esto desde un archivo por lotes: test.bat

set LF=^ 
    [blank line] 
    [blank line] 
    rem two blank lines needed above 
    set multi=Line 1!LF!Line 2!LF!Last line 
    echo !multi! 

estas salidas de tres líneas:

 Line 1 
     Line 2 
     Last line 

así que ¿cómo puedo obtener file.txt varentorno dentro de un archivo por lotes ?

+0

es el quilate^realmente en el archivo, o es que un marcador de posición para un CRLF? Supongo que esta es una máquina de Windows. – RobW

+0

El símbolo de intercalación está realmente en el archivo, es la forma de crear una variable que contenga un carácter de avance de línea. 'set LF = ^' seguido de dos líneas vacías – jeb

+0

gracias jeb para la aclaración –

Respuesta

7

Como dijo dbenham, también se puede hacer con/f pero es un poco más complicado.

La sencilla solución al 80% es

setlocal EnableDelayedExpansion 

set "var=" 
set LF=^ 


rem *** Two empty lines are required for the linefeed 
FOR /F "delims=" %%a in (myFile.txt) do (
    set "var=!var!!LF!%%a" 
) 
echo !var! 

pero fracasa con:
- Si una línea está en blanco que se omitirá
- Si una línea comienza con ; la EOL caracteres
- Si una línea contiene ! (y signos de intercalación)

Pero entonces usted podría utilizar un poco más compleja solución

@echo off 
SETLOCAL DisableDelayedExpansion 
set "all=" 
FOR /F "usebackq delims=" %%a in (`"findstr /n ^^ aux1.txt"`) do (
    set "line=%%a" 
    SETLOCAL EnableDelayedExpansion 
    set "line=!line:#=#S!" 
    set "line=!line:*:=!" 
    for /F "delims=" %%p in ("!all!#L!line!") do (
     ENDLOCAL 
     set "all=%%p" 
    ) 
) 
SETLOCAL EnableDelayedExpansion 
if defined all (
set "all=!all:~2!" 
set ^"all=!all:#L=^ 

!" 
set "all=!all:#S=#!" 
) 
echo !all! 

¿Qué hace el código?
primer lugar, el findstr /n ^^ antepondrá cada línea con un número de línea y dos puntos, al igual que

1:My first Line 
2:; beginning with a semicolon 
3: 
4:there was an empty line 

Esto resuelve el problema de las líneas vacías y también el estándar de EOL-carácter ; puede ser ignorada.
Para obtener el contenido de la línea, el valor se establece en una variable, mientras que la expansión retrasada está deshabilitada, esto resuelve el problema con los caracteres ! y ^.

Para eliminar el número de línea y los dos puntos, la expansión retrasada se habilitará (no, un delim de : no puede resolverlo).

Luego todos # se reemplazan por #S, esto se hará primero, ya que después del prefijo que quita la línea podría estar vacía y la sustitución fallaría.
¿Pero por qué lo reemplazo?
Eso es porque no puedo insertar los saltos de línea aquí, ya que el siguiente PARA/F fallaría con saltos de línea embebidos,
por lo que sólo añadir marcador de salto de línea (en este caso uso #L), pero el contenido del archivo podría contener también un #L, pero reemplazando todos # con #S todos los marcadores son únicos.

Después del marcador, existe el problema de cerrar/deshabilitar la expansión retrasada con un endlocal, pero conservar el contenido de las variables all y line modificadas.
Esto se hace con el truco FOR/F-endlocal, ya que el %%p puede transportar contenido detrás de la barrera endlocal.

Luego de leer el archivo completo, verifico si el all está definido, ya que estaría vacío para un archivo vacío.
Luego se eliminará el primer marcador de alimentación de línea#L, y todos los demás marcadores se reemplazarán por un carácter de avance de línea real.
Luego, el seguro más seguro #S se revertirá a #.

Eso es todo, por lo que incluso esta solución es obviamente ...

+0

+1, comencé a ir por la ruta FOR/F, pero luego pensé: "¿Por qué estoy haciendo todo este trabajo?" :-) – dbenham

+0

muy gracioso :) pero luego he venido como un saltamontes humilde, solo queriendo aprender las intracsies de DOS ... y me siento honrado de que le hayas dado el viejo intento de la universidad ... pero muchas gracias por todo tu trabajo, aquí y en el extranjero! Me quedaré en el camino –

+0

esto por supuesto es genial! como mi archivo fuente (aux) es realmente un archivo html que necesita ser insertado en un registro sql (y la fuente contiene! en la primera línea). ¡así que +2 por ese penetrante bit de código! así que ahora solo tengo que verificar el tamaño del archivo para asegurarme de que esté por debajo del límite de 8k, de lo contrario, puedo dividir el! todo! en! all1! ! all2 !, etc. aproximadamente la mitad de mis archivos son de 8k-30K, por lo que probablemente sea un máximo de cuatro o cinco. ¡Todos! var's gracias por compartir –

2

Usted estuvo casi allí. Necesita leer cada línea de texto y luego agregar la línea más un avance de línea a la variable.

FOR/F podría utilizarse, pero no funciona bien con la expansión demorada si el contenido contiene ! caracteres. También es incómodo conservar líneas en blanco y torpe para deshabilitar la opción EOL.

Una solución más simple es usar SET/P para leer las líneas. Las limitaciones de esta técnica son:

1) Se recorta posterior caracteres de control de cada línea

2) El archivo debe usar Windows terminadores de línea estándar de retorno de carro, avance de línea. No funcionará con la alimentación de línea de estilo de Unix.

3) Se limita a leer 1023 bytes por línea (sin incluir los caracteres de línea de terminación)

tener en cuenta que una variable de entorno sólo puede contener un poco menos de 8 Kbytes de datos. Por lo tanto, está limitado a solo cargar un archivo muy pequeño en una variable con esta técnica.

@echo off 
setlocal enableDelayedExpansion 
set LF=^ 


:: Two blank lines above needed for definition of LF - do not remove 
set file="test.txt" 
set "var=" 
for /f %%N in ('find /c /v "" ^<%file%') do set lineCnt=%%N 
<%file% (
    for /l %%N in (1 1 %lineCnt%) do (
    set "ln=" 
    set /p "ln=" 
    set "var=!var!!ln!!lf!" 
) 
) 
set var 
+0

gracias Sr. Benham! Estoy trabajando en esto ahora. –

+0

+1, ya que es la manera más simple y en la mayoría de los casos no necesita más – jeb

+0

, así que creo que podría empujar el límite con esto ya que mi archivo a veces supera 8k, así que tendré que analizar el archivo en dos o más variables ... así que está fuera de DOSville donde intentaré lo imposible :) –

Cuestiones relacionadas