windows - 批处理以从文本文件中删除带有开始和停止分隔符的行范围
问题描述
我知道批次不是最好的工具,但我的要求要求我保留它。
我的文本如下所示(它也有空行):
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%"
解决方案
一种可能且非常简单的方法是让特定的行标记切换一个标志,该标志指示是否要输出当前迭代的行:
@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
推荐阅读
- php - Ci PHP发送带有媒体的电子邮件在移动浏览器中不起作用
- node.js - 节点 - 在浏览器中下载现有的 excel
- html - 我的“ngSubmit”有时会出错
- kubernetes - 使用 Istio ServiceEntry 的域注册
- c# - 从 MS SQL 数据库获取数据到 Xamarin Android App Gridview
- python - 在 Python 模块而不是 __main__ 的上下文中执行 REPL 代码?
- email - 在 gsuite 中为不同的客户添加不同的 logo
- javascript - 使用JS水平滚动HTML表格
- arrays - DB 结果集后的慢速数组操作
- icinga2 - 如何修复 icinga2.service:主要进程已退出