2012-05-15 48 views
5

我有一个名为file.txt的包含文件:多行文本文件,如何投入变量的环境

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

我怎样才能将它放入一个的环境变量?

我可以从一个批处理文件这样做: 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! 

这个输出三行:

 Line 1 
     Line 2 
     Last line 

所以,我怎么能得到file.txt的进入ENVVAR一个批处理文件中?

+0

是克拉^真正的文件,或者是一个CRLF的占位符?我假设这是一台Windows机器。 – RobW

+0

插入符号确实在文件中,它是创建包含一个换行符的变量的方式。 '设置LF = ^'后面跟两条空行 – jeb

+0

感谢jeb的澄清 –

回答

7

正如dbenham所说,它也可以用for/f来完成,但它有点复杂。

简单的80%的解决方案是

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! 

但它失败:
- 如果行是空的,将被跳过
- 如果某行始于;的EOL字符
- 如果一行包含!(插入符和)

但你可以使用一点更复杂的解决方案

@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! 

代码的作用是什么?
首先,将findstr /n ^^预先考虑的行号和冒号的每一行,如

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

这解决的空行的问题,并且还标准EOL-字符;可以忽略。
要获取该行的内容,将该值设置为变量,同时禁用延迟扩展,这将解决!^字符的问题。

要删除行号和冒号,将启用延迟扩展(否,:的定界符无法解决它)。

然后将所有#替换为#S,这将首先完成,因为删除行前缀可能为空,并且替换将失败。
但我为什么要更换它?
那是因为我不能在这里插入换行,如下面的FOR/F将失败,并嵌入换行符,
所以我只加换行标志(在这种情况下,我使用#L),但文件的内容也可以包含#L,但通过用#S代替全部#,所有标记都是唯一的。

标记之后,存在关闭/禁用延迟扩展的问题,使用endlocal,但保留修改后的allline变量的内容。
这是通过FOR/F-endlocal技巧完成的,因为%%p可以将内容传输到endlocal屏障之后。

然后在读完整个文件后,我检查是否定义了all,因为它对于空文件是空的。
然后第一个换行标记#L将被删除,并且所有其他标记将被替换为实际换行字符。
然后更加安全的#S将恢复为#

这一切,所以即使这个解决方案显然是...

+0

+1,我开始沿着FOR/F路线走下去,但后来我想:“我为什么要做这一切工作? :-) – dbenham

+0

非常有趣:)但是后来我作为一个低grass come come come come only only only only only DOS DOS DOS ... ... ... and and and and and and and and and and and and and and and and and and and and many many many many many many many many many many many工作,在这里和国外!我会留在路径 –

+0

这当然是辉煌!因为我的源文件(aux)实际上是一个需要插入到sql记录中的html文件(并且源代码包含!在第一行)。所以+2对于那些有洞察力的代码!所以现在我只需要检查文件的大小,以确保它在8K的限制以下,如果不是的话,我可以分割!!进入!all1! !all2 !,等等。大约一半的文件是8k-30K,所以最多可能是4或5!all! VAR的。感谢分享 –

2

你几乎在那里。您需要读取文本的每一行,然后将该行和换行符附加到该变量。

可以使用FOR/F,但如果内容包含!个字符,则延迟扩展效果不佳。保留空白行也很尴尬,禁用EOL选项也很尴尬。

更简单的解决方案是使用SET/P来读取行。这种技术的局限性是:

1)从修剪每行

2尾随控制字符)的文件必须使用的回车,换行Windows标准行终止。它不适用于Unix样式换行。

3)被限制在读取每行1023个字节(不包括行结束字符)

记住,环境变量只能容纳一个略小于8千字节的数据。所以你只能用这种技术将一个非常小的文件加载到变量中。

@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

感谢Benham先生!即时在这工作。 –

+0

+1,因为这是最简单的方法,在大多数情况下,你不需要更多 – jeb

+0

我想我可能会推这个限制,因为我的文件有时会超过8K,所以我将不得不将一个文件解析为两个或更多的变量..因此,它关闭到DOSville,我将尝试不可能:) –