Cmd合并.txt文件并删除行

时间:2019-12-19 21:09:06

标签: batch-file cmd

我有3个Txt格式的文件,如下所示:

a.txt
b.txt
c.txt

我使用cmd合并了3个这样的文件:

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

现在文件已成功合并为一个,但是我希望在合并之前删除所有行,直到LINE name

  

交易结束

或。

TRANSACTION start

谢谢

2 个答案:

答案 0 :(得分:0)

以下注释的批处理文件代码可能可以用于此任务。

@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

使用Windows命令处理器cmd.exe处理的批处理文件来执行此文本文件合并任务绝对是此任务的最差选择。 cmd.exe设计用于执行命令和可执行文件,但不适用于文件内容处理任务。因此,必须使用特殊代码才能真正处理ANSI或UTF-8编码的文本文件的所有行,如我在How to read and print contents of text file line by line?的答案中所详细描述的那样,与其他解决方案相比,该特殊代码使文件处理极其缓慢使用以C / C ++ / C#编写的应用程序或编译为可执行文件的其他编程语言编写的程序,或默认安装在Windows上的其他脚本解释器(如Windows Script HostPowerShell)或其他脚本解释器(如Python或Perl)。

要了解所使用的命令及其工作方式,请打开command prompt窗口,在其中执行以下命令,并非常仔细地阅读每个命令显示的所有帮助页面。

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

也请阅读有关Using command redirection operators的Microsoft文章,以获取2>nul的解释。重定向操作符>必须在两个 FOR 命令行上使用插入符号^进行转义,并且使用2>nul在Windows命令解释程序处理此命令时将其解释为文字字符执行命令 FOR 之前的命令行,该命令在后台以dir和两者之间的命令行开始的单独命令进程中分别执行嵌入的findstr%ComSpec% /c命令行附加'

答案 1 :(得分:0)

将批处理脚本CD放入文件目录后,执行以下代码

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

对于每个目录文本文件,循环将

  • 读取文件中的行数
  • 将行数另存为var
  • 在文件中搜索包含字符串模式TRANSACTION END或TRANSACTION start的第一行
  • 创建一个临时文件,其原始文件内容从带有文件模式的行开始到文件的结尾
  • 删除添加到临时文件每行开头的多余字符
  • 将更新后的内容写回到原始文件名

循环完成后,临时文件将被删除