2014-03-03 73 views
0

我試圖從類似於此的垂直報表中刪除條目。使用批次根據多個條件刪除分隔符之間的文本

report start : hi good morning 
report (1234) hi 
10/10/2013 
line unequal 
good morning hi good morning (123:) 
20131212020202312312******** 
report start : hi good evening 
report (1234) hi 
10/10/2013 
good evening hi good evening (123:) 
20131212020202312312******** 
report start : hi good morning 
report (1234) hi 
10/10/2013 
good evening hi good evening (123:) 
20131212020202312312******** 

我試圖刪除完整的條目,其中「晚」是當前和「早晨」是沒有的。總之,該報告最終應該是這樣的:

report start : hi good morning 
report (1234) hi 
10/10/2013 
line unequal 
good morning hi good morning (123:) 
20131212020202312312******** 
report start : hi good morning 
report (1234) hi 
10/10/2013 
good evening hi good evening (123:) 
20131212020202312312******** 

我雖然對「* *」,其中每行會與一系列星號端之間串聯的一切。它們的長度始終相同。然後使用findstr刪除條目,但我該如何重構整個報表?它必須返回到垂直格式。爲了增加複雜性,結果在txt文件的各種縮進中。

我已經無法用「*」作爲delim中,因此,不能引入FOR/F循環來連接。這是我得到了多少。

感謝

+0

請解釋「條目」開始和結束的位置。你的輸出示例數據不符合你的解釋......也許你可能會在例子中計算輸入和輸出線。 – Aacini

+0

@Aacini「條目」將從第一行文本開始,以「20131212020202312312 ********」之類的內容結束。除第一行外,每個「條目」前都會加上「20131212020202312312 ********」。我在這個例子中犯了一個錯誤,我的錯誤。 – user3375545

回答

1
@ECHO OFF 
SETLOCAL 
:: make a tempfile 
:maketemp 
SET "tempfile=%temp%\%random%" 
IF EXIST "%tempfile%*" (GOTO maketemp) ELSE (ECHO.>"%tempfile%a") 
:: Process file, count sections and record section numbers to remove 
SET /a section=0 
CALL :init 
FOR /f "delims=" %%a IN (q22151608.txt) DO (
ECHO %%a|FINDSTR "evening" >NUL 
IF NOT ERRORLEVEL 1 SET found1=Y 
ECHO %%a|FINDSTR "morning" >NUL 
IF NOT ERRORLEVEL 1 SET found2=Y 
ECHO %%a|FINDSTR /e "********" >NUL 
IF NOT ERRORLEVEL 1 CALL :endsection 
) 
:: Re-process file, count sections 
SET /a section=0 
CALL :init 
(
FOR /f "delims=" %%a IN (q22151608.txt) DO (
IF NOT DEFINED found1 CALL :switch 
IF DEFINED found2 ECHO(%%a 
ECHO %%a|FINDSTR /e "********" >NUL 
IF NOT ERRORLEVEL 1 CALL :init 
) 
)>newfile.txt 
DEL "%tempfile%a" 

GOTO :EOF 

:switch 
SET found1=Y 
FIND "#%section%#" "%tempfile%a" >NUL 
IF ERRORLEVEL 1 SET found2=Y 
GOTO :eof 

:endsection 
IF DEFINED found1 IF NOT DEFINED found2 >>"%tempfile%a" ECHO(#%section%# 
:init 
SET "found1=" 
SET "found2=" 
SET /a section+=1 
GOTO :eof 

我用了一個包含您的數據,我的測試命名爲q22151608.txt文件。輸出到文件newfile.txt

您的輸出描述不符合您的問題定義。如果我已正確解釋您的描述,則不應出現line unequal行。

最好發佈實際數據適當審查,而不是人爲的數據。目前還不清楚哪一部分開始和結束。即使像更改時間戳報告號這樣簡單的事情也會使提供的數據更清晰。

+0

我糾正了我的第一篇文章。抱歉的錯誤。這些報告無限延長,因此很難完全在這裏發佈。 – user3375545

+0

工作。謝謝! – user3375545

1

正則表達式可以是你的朋友:)像awk或sed這樣的工具可以很好地工作 - 免費的Windows端口可用。

我寫了REPL.BAT - a hybrid JScript/batch utility執行正則表達式搜索和替換標準輸入並將結果寫入標準輸出。這是純粹的腳本,可以在XP以後的任何Windows機器上本機運行。完整的文檔嵌入在腳本中。

假設REPL.BAT是在當前目錄中,或者更好的是,地方你的PATH中,那麼你需要的是以下幾點:

type source.txt|repl "^report start :(?:[\s\S](?!morning))*?evening(?:[\s\S](?!morning))*?^\d*\*{8}\r?\n" "" m >output.txt 

以上使用M選項可啓用跨多行搜索,這需要將整個源文件加載到內存中。這對於真正大的輸入文件可能會產生問題。但是這比使用FOR/F的純批處理解決方案更好,因爲該命令還會將整個源文件緩存在內存中。

0
@echo off 
setlocal EnableDelayedExpansion 

set i=0 
set "morning=" 
set "evening=" 
for /F "delims=" %%a in (test.txt) do (
    set /A i+=1 
    set "line[!i!]=%%a" 
    set "line=%%a" 
    if "!line:morning=!" neq "%%a" set morning=present 
    if "!line:evening=!" neq "%%a" set evening=present 
    if "!line:~-4!" equ "****" (
     set "remove=" 
     if defined evening if not defined morning set remove=true 
     if not defined remove for /L %%i in (1,1,!i!) do echo !line[%%i]! 
     set i=0 
     set "morning=" 
     set "evening=" 
    ) 
) 
0

還有一個。在這種情況下使用中間臨時文件。

@echo off 
    setlocal enableextensions disabledelayedexpansion 

    :: configure and clean ouput/temporary files 
    set "inputFile=inputFile.txt" 
    set "outputFile=outputFile.txt" 
    set "tempFile=%temp%\%~nx0.tmp" 
    break>"%tempFile%" 
    break>"%outputFile%" 

    :: retrieve end of section lines 
    for /f "tokens=1 delims=:" %%a in ('findstr /n /l /e /c:"****" "%inputFile%"') do set "_sect.%%a=1" 

    :: extract each section and test for inclusion in output file 
    for /f "tokens=1,* delims=:" %%a in ('findstr /n "^" "%inputFile%"') do (
     echo(%%b>>"%tempFile%" 
     if defined _sect.%%a (
      find /i "morning" "%tempFile%" >nul && (type "%tempFile%">>"%outputFile%") 
      break>"%tempFile%" 
     ) 
    ) 

    :: clean and exit 
    del /q "%tempFile%" 2>nul 
    endlocal 
相關問題