首页 > 解决方案 > 批次 | 在循环中的两行之间复制文本

问题描述

我想将所有部分从LOAD后续;(分号)复制到一个循环中。我是批处理的新手,我想知道是否可以使用批处理来执行此操作,谢谢。

这是我的 txt 文件:

ALTER TABLE DRIVE(ID);      
SELECT COUNT(*) DRIVE;   
LOAD INTO ID, VALUES                                         
CAR , BUS,  LIMO); 

ALTER TABLE TEMP(ID);      
SELECT COUNT(*) TEMP;   
LOAD INTO ID, VALUES                                         
HOT , COLD,  OK); 

我需要一切LOAD;

LOAD INTO ID, VALUES                                         
CAR , BUS,  LIMO); 

我的想法:

  1. 在 text 中搜索 first LOAD-> save line-number1,然后在 text- ;save line-number2 中搜索下一个。
  2. 然后在目标 txt 文件中复制块(从第 1 行到第 2 行的所有内容)。
  3. 删除所有文本直到第 2 行。
  4. 再次启动脚本(循环)并将每个新文本块添加到目标文件。
  5. 在到达文本结尾并且文本中没有时结束脚本LOAD
@echo off

set "dataFile=C:\Users\ebeta\Desktop\work3\data.txt"

rem search the starting line
    set "startLine="
    for /f "tokens=1 delims=:" %%a in (
        'findstr /l /b /n /c:"LOAD" "%dataFile%"'
    ) do if not defined startLine set "startLine=%%a"

rem remove all lines before the starting one    
    if defined startLine for /f "tokens=1,* delims=:" %%a in (
        'findstr /n "^" "%dataFile%" ^& break ^> "%dataFile%"'
    ) do if %%a geq %startLine% >>"%dataFile%" echo(%%b

rem search the semicolon line
    set "semicolonLine="
    for /f "tokens=1 delims=:" %%a in (
        'findstr /l /b /n /c:";" "%dataFile%"'
    ) do if not defined semicolonLine set "semicolonLine=%%a" 


    sed -n '%startLine%','%semicolonLine%' > target.txt

rem remove all lines before the semicolon one    
    if defined semicolonLine for /f "tokens=1,* delims=:" %%a in (
        'findstr /n "^" "%dataFile%" ^& break ^> "%dataFile%"'
    ) do if %%a geq %semicolonLine% >>"%dataFile%" echo(%%b

    )
)

goto start

标签: batch-file

解决方案


@echo off
setlocal

set "target=C:\Users\ebeta\Desktop\work3\data.txt"
set "found="

for /f "delims=" %%A in ('type "%target%" ^& break ^> "%target%"') do (
    if defined found (
        >> "%target%" echo %%A
        echo %%A| findstr /r /c:"; *$" >nul && set "found="
    ) else for /f "delims= " %%B in ("%%~A") do (
        if "%%~B" == "LOAD" (
            >> "%target%" echo %%A
            set "found=1"
        )
    )
)

这不会从行尾修剪任何空格,因为问题中的示例确实有尾随空格。特殊字符可能是echo管道传输到的问题findstr。我尝试了延迟扩展版本,但仍然可能出现问题。

替代:

@echo off
setlocal

set "target=C:\Users\ebeta\Desktop\work3\data.txt"
set "pattern=(?sm)^LOAD .+?;"

powershell -noprofile -command^
 "$content = get-content -path '%target%' -raw;"^
 "$content = $content -replace '(?m)\s+$','';"^
 "$load = select-string '%pattern%' -input $content -allmatches;"^
 "if ($load.matches.count -eq 0) {exit 1};"^
 "set-content -path '%target%' -value $load.matches -force"

if errorlevel 1 (
    >&2 echo No replacements occurred.
    exit /b 1
)

此代码用于powershell修剪尾随空格并获取感兴趣的文本。如果发生替换,则为errorlevel0否则为1。不知道有什么问题。最后if errorlevel 1只是展示如何检查是否发生故障。仅在target确实发生替换时才写入,这与擦除文件的先前代码不同。如果您想要一个没有替换的空白文件,请删除powershell命令的倒数第二行:

"if ($load.matches.count -eq 0) {exit 1};"^

是要删除的可选行。


推荐阅读