-1

i have 3 file in Txt format like this:

a.txt
b.txt
c.txt

I merge 3 file like this using cmd:

For %I In ("%CD%")Do @Copy *.* "%~nxI.txt"

and now the file has been successfully merged into one but I want before merge to delete all lines until LINE name

TRANSACTION END

or .

TRANSACTION start

Thank You

Art P
  • 1
  • I thought that this question had a similarity to an earlier question, but this comes up as your first. Imagine my surprise, when I found [this question](https://stackoverflow.com/q/59416476), from earlier, by a member with the same, avatar!. Anyhow, the point is, we need to see the expected content of those three files, and that member had shown more of that than you have. – Compo Dec 19 '19 at 23:28

2 Answers2

0

The following commented batch file code could be perhaps used for this task.

@echo off
setlocal EnableExtensions DisableDelayedExpansion
rem Use name of current folder as output file name.
for %%I in (.) do set "OutputFile=%%~nxI.txt"

rem Is the current folder not root folder of a drive?
if not "%OutputFile%" == ".txt" goto DeleteOutputFile

rem Use for root folder of a drive a generic file name containing drive letter.
for %%I in (.) do set "OutputFile=%%~dI"
set "OutputFile=RootDrive%OutputFile:~0,1%.txt"

:DeleteOutputFile
del "%OutputFile%" 2>nul

rem Get a list of *.txt files in current directory into memory of Windows
rem command processor not containing the output file which will have also
rem the file extension .txt and will be stored also in current directory.
rem Then process this list of text files with ignoring all lines up to
rem first line containing case-insensitive either TRANSACTION END or
rem TRANSACTION START. The code below is written to really output every
rem line in the text files below the line with one of the identifier
rem strings including empty lines and lines starting with a semicolon.

for /F delims^=^ eol^= %%I in ('dir *.txt /A-D /B /ON 2^>nul') do (
    set OutputLines=
    for /F delims^=^ eol^= %%J in ('%SystemRoot%\System32\findstr.exe /N "^" "%%I" 2^>nul') do (
        set "Line=%%J"
        setlocal EnableDelayedExpansion
        if defined OutputLines (
            echo(!Line:*:=!
            endlocal
        ) else (
            if not "!Line:TRANSACTION END=!" == "!Line!" (
                endlocal
                set "OutputLines=1"
            ) else if not "!Line:TRANSACTION START=!" == "!Line!" (
                endlocal
                set "OutputLines=1"
            ) else endlocal
        )
    )>>"%OutputFile%"
)

rem Delete the output file if being an empty file because of text files
rem found in current directory, but none of them contain a line with one
rem of the two identifier strings.

if exist "%OutputFile%" for %%I in ("%OutputFile%") do if %%~zI == 0 del "%OutputFile%"
endlocal

Doing this text file merging task with a batch file processed by Windows command processor cmd.exe is definitely the worst choice for this task. cmd.exe is designed for executing commands and executables, but not for file content processing tasks. For that reason special code is necessary to really process all lines of ANSI or UTF-8 encoded text files as described in full detail in my answer on How to read and print contents of text file line by line? This special code makes processing of the files extremely slow in comparison to other solutions using either an application written in C/C++/C# or other programming languages compiled to an executable or other script interpreters like Windows Script Host or PowerShell both installed by default on Windows or other script interpreters like Python or Perl.

To understand the commands used and how they work, open a command prompt window, execute there the following commands, and read the displayed help pages for each command, entirely and carefully.

  • del /?
  • dir /?
  • echo /?
  • endlocal /?
  • findstr /?
  • for /?
  • goto /?
  • if /?
  • set /?
  • setlocal /?

Read also the Microsoft article about Using command redirection operators for an explanation of 2>nul. The redirection operator > must be escaped with caret character ^ on both FOR command lines using 2>nul to be interpreted as literal character when Windows command interpreter processes this command line before executing command FOR which executes the embedded dir respectively findstr command line with using a separate command process started in background with %ComSpec% /c and the command line between the two ' appended.

Mofi
  • 46,139
  • 17
  • 80
  • 143
0

Once your batch script cd's to the file directory, execute the below code

for /F delims^=^ eol^= %%I in ('dir *.txt /A-D /B /ON 2^>nul') do (
  powershell -command "(gc %%I) | Measure-Object -Line | tee temp">nul
  powershell -command "(gc temp) | Select-Object -Skip 4">temp && set /p LineTotal=<temp
  powershell -command "(gc %%I | Select-String -Pattern 'TRANSACTION END','TRANSACTION start' -SimpleMatch -Context 0,%LineTotal%) | ForEach-Object { $_ -replace '^[\x3E] |','' } | Set-Content temp"
  powershell -command "gc temp | ForEach-Object { $_ -replace '^  |','' } | Set-Content %%I"
  )
if exist temp del temp

For each directory text file, the loop will

  • Read the number of lines in the file
  • Save the line count as a var
  • Search the file for first line containing sting pattern TRANSACTION END or TRANSACTION start
  • Create a temp file with the original file contents starting from the line with the file pattern to the end of the file
  • Remove extra characters added to the beginning of each line of the temp file
  • Write the updated contents back to the original file name

Once the loop completes, the temp file is deleted

David
  • 134
  • 7
  • David, it seems like this would be speedier and more efficient were you to leverage `powershell.exe` once within the loop, _instead of four times_. I would also like to advise the OP, _whichever one it is_, that as this is overwriting the files, they had better have full backups of every `.txt` file before testing your, _or anyone else's_, code. – Compo Dec 29 '19 at 22:58