【问题标题】:loop through file saving to variable循环文件保存到变量
【发布时间】:2024-01-21 15:36:01
【问题描述】:

我现在可以使用以下 bat 文件(它允许在文件的每一行末尾添加文本)——另请参阅: bat file: Use of if, for and a variable all together

@echo off
setLocal EnableDelayedExpansion

IF EXIST "%FileToModify1%"  (
  for /f "tokens=* delims= " %%a in (%FileToModify1%) do (
    echo %%a   Note:  certain conditions apply  >> "%SaveFile1%"
  ) 
)

但是,我想将每一行保存到一个变量中(包括换行符),然后将变量回显到最后的文件中。由于文件中有几行,因此将每一行保存到文件中确实效率低下。

我尝试用谷歌搜索,但答案不适合我的情况......

基本上我需要用于连接和保存到变量的语法(累积起来就像 C# 中的“+=”),还需要使用新行...

【问题讨论】:

    标签: windows variables batch-file cmd string-concatenation


    【解决方案1】:

    其实你不需要把所有的东西都放到一个变量中,你只需要把重定向放在另一个位置。 试试这个:

    @echo off
    setlocal EnableDelayedExpansion
    
    if exist "%FileToModify1%" (
        for /F "usebackq delims=" %%a in ("%FileToModify1%") do (
            echo %%a   Note:  certain conditions apply
        )
    ) > "%SaveFile1%"
    
    endlocal
    

    请注意,for /F 会忽略原始文件中的空行,因此它们不会转移到新文件中。以; 开头的行也会被for /F 忽略(除非您更改eol 选项——请参阅for /?)。

    我修改了for /F 选项:

    • 不允许使用delims,因此每行都按原样输出(使用"tokens=* delims= ",如果存在,则从每行中删除前导空格);
    • usebackq 允许在 "" 中包围文件规范,如果它包含空格,这将很有帮助;

    附录 A

    如果你还想把文件内容存入一个变量,你可以这样做:

    @echo off
    setlocal EnableDelayedExpansion
    
    rem the two empty lines after the following command are mandatory:
    set LF=^
    
    
    if exist "%FileToModify1%" (
        set "FileContent="
        for /F "usebackq delims=" %%a in ("%FileToModify1%") do (
            set "FileContent=!FileContent!%%a   Note:  certain conditions apply!LF!"
        )
        (echo !FileContent!) > "%SaveFile1%"
    )
    
    endlocal
    

    文件内容存储在变量FileContent中,包括附录Note: certain conditions applyLF 包含换行符。

    注意:
    变量的长度非常有限(据我所知,Windows XP 以来为 8191 字节,更早为 2047 字节)!

    [参考:
    Store file output into variable(最后一个代码片段);
    Explain how dos-batch newline variable hack works]


    附录 B

    或者,您可以将文件内容存储在数组中,如下所示:

    @echo off
    setlocal EnableDelayedExpansion
    
    if exist "%FileToModify1%" (
        set /A cnt=0
        for /F "usebackq delims=" %%a in ("%FileToModify1%") do (
            set /A cnt+=1
            set "Line[!cnt!]=%%a   Note:  certain conditions apply"
        )
    
        (for /L %%i in (1,1,!cnt!) do (
            echo !Line[%%i]!
        )) > "%SaveFile1%"
    )
    
    endlocal
    

    文件的每一行都存储在数组Line[1]Line[2]Line[3]等中,包括附录Note: certain conditions applycnt 包含总行数,即数组大小。

    注意:
    实际上,这不是真正的数组数据类型,因为它不存在于批处理中,它是具有数组样式命名的标量变量的集合(Line[1]Line[2],...);因此可以称之为伪数组。

    [参考:
    Store file output into variable(第一个代码片段);
    How to create an array from txt file within a batch file?]

    【讨论】:

    • 虽然这个答案很好,可以接受,并且可能比保存到变量更好,但如果有人知道如何做到这一点,它可能会帮助其他来到这里的人.....
    • 我编辑了我的答案并将我以前(已删除)的 cmets 添加为附录,包括代码 sn-ps 和参考;我希望它有用...
    【解决方案2】:

    您可以一次性编写输出文件:

    (
      for /l %%i in (0,1,10) do (
       echo line %%i
      )
    )>outfile.txt
    

    (比单独添加每一行要快得多)

    【讨论】: