首页 > 解决方案 > 批处理以从文本文件中删除带有开始和停止分隔符的行范围

问题描述

我知道批次不是最好的工具,但我的要求要求我保留它。

我的文本如下所示(它也有空行):

Line AAA text

Line BBB text
! ***@@@ START
Body text here
! ***@@@ END
Line XXX
Line YYY
!Comment Line etc

我想删除!***@@@ START 和 END 行以及其间的所有内容,然后保存在原始文件上。

我找到并修改了下面的代码,但它去掉了我的空白行和!人物。

@echo off
setlocal enabledelayedexpansion
set "sourceFile=c:\temp\startfile.txt"
set "tempFile=c:\temp\tempfile.txt"
set "StartPhrase=! ***@@@ START"
set "EndPhrase=! ***@@@ END"
set /a lineNum=0

REM check file for search phrase, store line as refLine
FOR /F "delims=" %%i IN (%sourceFile%) DO (
    set /a lineNum+=1
    echo !lineNum! = "%%i"
    if "%%i" == "%StartPhrase%" (
        echo Found "%StartPhrase%" on line !lineNum!
        set /a StartrefLine=!lineNum!
    )
        if "%%i" == "%EndPhrase%" (
        echo Found "%EndPhrase%" on line !lineNum!
        set /a EndrefLine=!lineNum!
    )
)

REM make backup
copy "%sourceFile%" "%sourceFile%-%DATE:/=-% %TIME::=-%.txt"

echo. 2>%tempFile%

REM Rewrite file 
set /a lineNum=0
    set /a lowEnd=%StartrefLine%
    echo "Set low end to %lowEnd%"
    set /a highEnd=%EndrefLine%
    echo "Set high end to %highEnd%"
FOR /F "delims=" %%i IN (%sourceFile%) DO (
    set /a lineNum+=1
    if !lineNum! GTR %lowEnd% (
        if !lineNum! LSS %highEnd% (
           echo "Skipping line #!lineNum!"
        )
    )
    if !lineNum! LSS %lowEnd% (
        echo "Writing Line !lineNum! %%i to temp file..."
        echo %%i >> %tempFile%
    )

    if !lineNum! GTR %highEnd% (
        echo "Writing Line !lineNum! %%i to temp file..."
        echo %%i >> %tempFile%
    )
)

REM get target filename only 
for %%F in ("%sourceFile%") do set fname=%%~nxF
REM del original file and rename tempfile
echo "Deleting original file..."
echo Y | del "%sourceFile%"
echo "Renaming %tempFile% to %fname%"
ren "%tempFile%" "%fname%"

标签: windowsbatch-filecmd

解决方案


一种可能且非常简单的方法是让特定的行标记切换一个标志,该标志指示是否要输出当前迭代的行:

@echo off
setlocal EnableExtensions DisableDelayedExpansion

rem // Define constants here:
set "_FILE=C:\TEMP\startfile.txt"
set "_TMPF=%TEMP%\%~n0_%RANDOM%.tmp"
set "_START=! ***@@@ START"
set "_END=! ***@@@ END"

rem // Initialise flag:
set "FLAG=#"
rem // Write to temporary file:
> "%_TMPF%" (
    rem /* Loop through lines of input file; `findstr` precedes each line with
    rem    line number plus `:`, so they do not appear empty to `for /F`: */
    for /F "delims=" %%L in ('findstr /N "^" "%_FILE%"') do (
        rem // Store current line string (with line number prefix) to variable:
        set "LINE=%%L"
        rem // Toggle delayed expansion to avoid loss of `!`:
        setlocal EnableDelayedExpansion
        rem // Remove line number prefix to retrieve original line string:
        set "LINE=!LINE:*:=!"
        rem // Check contents of current line:
        if "!LINE!"=="!_START!" (
            endlocal & set "FLAG="
        ) else if "!LINE!"=="!_END!" (
            endlocal & set "FLAG=#"
        ) else (
            rem // Check state of flag for outputting:
            if defined FLAG echo(!LINE!
            endlocal
        )
    )
) && (
    rem // Move temporary file onto target file:
    move /Y "%_TMPF%" "%_FILE%"
)

endlocal
exit /B

推荐阅读