我需要解析一个文本文件。我想在文本文件中找到第一行
: the first line to find
set firstLine=------------------------------------------------------------------------------------------------------------------
并找到最后一行
:: the last line to find
set lastLine=*******************************************************************************************************************
然后我需要将这两行之间的所有内容导出到一个新文件中。
echo >> M:TESTINGOutput.txt
我是这方面的初学者,我已经搜索了好几天,但找不到如何做到这一点。
我查看了循环和if语句,但我仍然感到困惑。
for /f "tokens=1 delims= " %%f in (M:TESTING*.txt) do (
:: sets then the line variable to the line just read
set line=%%f
:: the first line to find
set firstLine=------------------------------------------------------------------------------------------------------------------
:: the last line to find
set lastLine=*******************************************************************************************************************
Then if %line% = %fistLine% start the export.....
任何指示都将不胜感激。谢谢
@DennisvanGils的方法是一个良好的开端,在许多情况下都会做得很好
然而,它不会在给定的行之间生成文本文件内容的精确副本:
- 前导空白(SPACE和TAB
- 以
;
开头的行将被跳过(由于for /F
的默认选项eol=;
),并且- 空行也将被跳过(因为
for /F
总是跳过这样的行) - 以
要获得文本文件部分的精确副本,可以使用以下代码片段:
@echo off
set "INFILE=M:TESTINGinput.txt"
set "OUTFILE=M:TESTINGoutput.txt"
set "FIRSTLINE=------------------------------------------------------------------------------------------------------------------"
set "LASTLINE=*******************************************************************************************************************"
setlocal EnableExtensions DisableDelayedExpansion
set "FLAG="
> "%OUTFILE%" (
for /F "delims=" %%L in ('findstr /N "^" "%INFILE%"') do (
set "LINE=%%L"
setlocal EnableDelayedExpansion
set "LINE=!LINE:*:=!"
if "!LINE!"=="%FIRSTLINE%" (
endlocal
set "FLAG=TRUE"
) else if "!LINE!"=="%LASTLINE%" (
endlocal
goto :CONTINUE
) else if defined FLAG (
echo(!LINE!
endlocal
) else (
endlocal
)
)
)
:CONTINUE
endlocal
这里的核心函数是findstr
,它被配置为返回文件中的每一行,并以行号和冒号:
为前缀。然后,它的输出由for /F
循环解析。由于前缀的原因,没有一行显示为空,因此每个行都由循环迭代。在循环的主体中,前缀由每行的set "LINE=!LINE:*:=!"
命令删除。
变量CCD_ 10用于决定是否要输出当前线路;如果定义了它,即分配了一个值,则执行命令tokens=*
1;否则就不是了。如果当前行与CCD_ 13中的字符串匹配,则设置CCD_;如果该行与%LASTLINE%
中的字符串匹配,则执行中断循环的goto
命令。这也意味着仅输出%FIRSTLINE%
和%LASTLINE%
匹配之间的第一块。
如果文本文件中可能出现多个%FIRSTLINE%
和%LASTLINE%
匹配,并且您希望输出每个块,请将goto
命令行替换为set "FLAG="
。
请注意,这种方法不检查%FIRSTLINE%
是否出现在%LASTLINE%
之前,甚至不检查是否存在%LASTLINE%
(在这种情况下,输出文件末尾的所有剩余行)。如果所有这些都很重要,那么逻辑就需要改进,甚至很可能需要第二个循环。
在这种情况下,您应该使用一个类似布尔值的变量来了解是否遇到了开始行和结束行,以及是否必须输出这些行。
此外,您应该将setlocal ENABLEDELAYEDEXPANSION
与!
一起使用,而不是使用%
,这样您就可以更改循环和if中的变量(有关详细信息,请参阅此。在这种情况下,不需要在if后面使用(),因为if在一行,但在我看来,它们使事情更容易阅读。如果您也想输出起始线和结束线,请切换对起始线和终止线的检查。
@echo off & setlocal ENABLEDELAYEDEXPANSION
set start=0
:: the first line to find
set firstLine=------------------------------------------------------------------------------------------------------------------
:: the last line to find
set lastLine=*******************************************************************************************************************
for /F "tokens=*" %%A in (TEST.txt) do (
:: sets then the line variable to the line just read
set line=%%A
if "!line!"=="!lastLine!" (set start=0)
if !start! equ 1 (echo !line!>>TESTOUTPUT.txt)
if "!line!"=="!firstLine!" (set start=1)
)
这应该是你想要的。请注意,当您第二次遇到启动线时,它会重新开始读取。