批处理文件 - 找到两行然后复制这些行之间的所有内容

时间:2015-11-10 20:19:49

标签: batch-file

我需要解析一个文本文件。 我想找到文本文件中的第一行

: the first line to find
set firstLine=------------------------------------------------------------------------------------------------------------------

找到最后一行

:: the last line to find
set lastLine=*******************************************************************************************************************

然后我需要将这两行之间的所有内容导出到新文件。

echo     >> M:\TESTING\Output.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.....

任何方向将不胜感激。感谢。

2 个答案:

答案 0 :(得分:3)

@ DennisvanGils' approach是一个良好的开端,在许多情况下表现良好 但是,它不会在给定行之间生成文本文件内容的精确副本:

    将删除
  • 前导空格( SPACE TAB )(由于tokens=*选项),
  • ;开头的行将被跳过(由于eol=;的默认选项for /F),
  • 也会跳过空行(因为for /F总是跳过这样的行)。

要获取文本文件部分的精确副本,您可以使用以下代码段:

@echo off
set "INFILE=M:\TESTING\input.txt"
set "OUTFILE=M:\TESTING\output.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:*:=!"命令都会删除前缀。

变量FLAG用于决定是否输出当前行;如果已定义,即分配了值,则执行命令echo !LINE!;否则不是。如果当前行与FLAG中的字符串匹配,则设置%FIRSTLINE%;如果该行与%LASTLINE%中的字符串匹配,则执行goto命令,该命令会中断循环。这也意味着只输出%FIRSTLINE%%LASTLINE%之间匹配的第一个块。

如果文本文件中可能出现多个%FIRSTLINE%%LASTLINE%匹配项,并且您希望输出每个块,请将goto命令行替换为set "FLAG="

请注意,此方法不检查%FIRSTLINE%之前是否发生%LASTLINE%,也不检查%LASTLINE%是否存在(文件末尾的所有剩余行都输出) )。如果这一切都很重要,那么逻辑需要改进,甚至最有可能需要第二个循环。

答案 1 :(得分:2)

在这种情况下你应该做的是使用像boolean这样的变量来知道你是否遇到了起始线和终止线,并知道你是否必须输出这些线。

此外,您应该setlocal ENABLEDELAYEDEXPANSION使用!代替%,这样您就可以更改循环和ifs中的变量(有关详细信息,请参阅this。如果在这种情况下不需要if,则使用()if,因为if在一行上,但是在我看来它们使事情更容易阅读。如果你想输出起点和终点,也要切换检查开始和endlines。

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

这应该做你想要的。请注意,当您第二次遇到起始线时,它会再次开始阅读。