Parsing 解析多个文本文件并将其重新创建为一个集合模板

Parsing 解析多个文本文件并将其重新创建为一个集合模板,parsing,batch-file,Parsing,Batch File,我对批处理编程不是很有经验。我有点纠结在一起的各种代码片段,但它不太工作,因为我想它太多 问题就在这里。日志文件在目录中创建。有些是多个条目,有些是单个条目。它们都遵循特定的模式。F.ex START STRING 1234 NAME1 ADRESS1 ETC NAME2 ADRESS2 ETC NAME3 ADRESS3 ETC 有时一个文件中有多个名称条目,有时只是一个条目。所有文件都有起始字符串。我需要做的是解析这些日志文件并在另一个目录中重新创建它们,一

我对批处理编程不是很有经验。我有点纠结在一起的各种代码片段,但它不太工作,因为我想它太多

问题就在这里。日志文件在目录中创建。有些是多个条目,有些是单个条目。它们都遵循特定的模式。F.ex

    START STRING 1234
    NAME1 ADRESS1 ETC
    NAME2 ADRESS2 ETC
    NAME3 ADRESS3 ETC
有时一个文件中有多个名称条目,有时只是一个条目。所有文件都有起始字符串。我需要做的是解析这些日志文件并在另一个目录中重新创建它们,一个文件中的每个名称对应一个文件,每个文件的格式都是一个命名文件。使用上述示例,它将创建3个文件,每个文件如下所示:

    START STRING
    NAME ADRESS ETC
这是迄今为止的代码。这有点管用。。除非目录中一次有一个以上的日志文件,否则我最终会得到几个条目,其中只有两个开始字符串,这是我需要避免的。换句话说,我需要它分别检查每个日志文件,而不是像我假设的那样,将所有日志文件视为一个大文本文件

    @Echo off
    @setlocal enableextensions enabledelayedexpansion


    :::First find out how many lines a file has.
    Set _File=*.log
    Set /a _Lines=0
    For /f %%j in ('Type %_File%^|Find "" /v /c') Do Set /a _Lines=%%j
    set /a "linecount= _Lines"


    :::Grab the first line always and then create a new file depending on how many         lines the file contained
    :LOOP
    if %linecount% GEQ 2 ( 
        set /a "linecount = linecount - 1"
        set lines=1 %linecount%
        set curr=1
            for /f "delims=" %%a in ('type *.log') do (
                    for %%b in (!lines!) do (
                    if !curr!==%%b echo %%a >> c:\temp\logs\%linecount%.log
                    )
                set /a "curr = curr + 1"
            )
    )
    if %linecount% GEQ 2 (GOTO LOOP)
    endlocal

我很确定有一个更聪明的方法可以做到这一点,但这是我所能做到的。想知道我是否可以简单地匹配开始字符串并以某种方式将其删除,而不删除第一行,或者最好是避免将双开始字符串放在一起。

您的问题描述不清楚,但从代码判断,我假设您只是想在新文件夹中重新创建每个日志文件,仅保留每个原始文件的前两行

如果是这样,那么这就是您所需要的:

@echo off
setlocal
set "sourceMask=.\*.log"
set "targetPath=test"
set "keepCount=2"

for %%F in ("%sourceMask%") do (
  <"%%~F" (
    for /l %%N in (1 1 %keepCount% ) do (
      set "ln="
      set /p "ln="
      echo(!ln!
    )
  ) >"%targetPath%\%%~nxF"
)
这应该满足您的要求-IIUC,从源中的每个
.log
文件,在目标中创建一个包含2行的文件-相应源日志文件起始行后的名称行。(好吧,如果这不是你想要的,这就是这个例行程序将要做的…)

  • 它处理源目录中应用于
    %%f
    的每个文件名
  • 在每个新文件名处,清除
    startine
  • 将第一行的内容分配给
    startine
  • 对于剩余的每一行
    • filename
      设置为目标中的新文件名,并向其中写入新的行
    • %%i
      中的名称行输出到生成的文件名
请注意,
启用延迟扩展
允许
!文件名
to指的是
filename
的内容,因为它在
的上下文中为…%%i..


例程
:nextfilename
在它自己的上下文中,因此%var%的含义更为熟悉。该例程只是从
filecount
中建立一个名称,并递增
filecount
,检查文件是否已经存在,然后重复,直到找到一个全新的文件名。然后将标题行写入该文件名。

如果日志文件有多个名称,您希望保留哪个名称?第一个?最后一个?原始日志文件的名称并不重要,因为一旦对它们进行了解析,它们就会被删除。一旦解析了文件,调用什么也无关紧要。在本例中,它们将被称为2.log、3.log等。我的拙见是,如果你在发布问题后的某个时间更改了你的问题要求,你应该等待更长的时间,然后将问题关闭为“已解决”;否则,当你的问题不完整且无法解决时,你会忽视最初阅读你问题的人…:(啊,很抱歉,我的描述有点模糊。如果一个文件中有3个名称,我需要它创建3个单独的文件,每个文件在一行上以开始字符串开头,在下一行上以名称开头。当目录中有两个日志文件时,问题就会出现。然后,它将它们视为一个大文件,这意味着开始字符串将出现在一个文件中出现两次,因为我的程序总是在每个新文件中添加第一行。出于某种原因,它将多个文件视为一个大文本文件,这意味着开始字符串出现多次。@user2463125-好的,我想我现在理解了您的要求。请查看我在修订答案中的第二次尝试。
@echo off
setlocal disableDelayedExpansion
set "sourceMask=.\*.log"
set "targetPath=test"
set "targetName=0"

for %%F in ("%sourceMask%") do (
  set "startString="
  for /f usebackq^ delims^=^ eol^= %%A in ("%%~F") do (
    if not defined startString (set "startString=%%A") else (
      set "nameString=%%A"
      set /a targetName+=1
      setlocal enableDelayedExpansion
      (
        echo(!startString!
        echo(!nameString!
      ) >"!targetPath!\!targetName!.log"
      endlocal
    )
  )
)
@ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION 
:: directories in question
SET destdir=c:\destdir
SET sourcedir=c:\sourcedir
SET /a filecount=0
:: process each .log file in source
FOR %%f IN (%sourcedir%\*.log) DO (
 SET "startline="
 FOR /f "usebackqdelims=" %%i IN ("%%f") DO (
  IF DEFINED startline (
   CALL :nextfname
   >>!filename! ECHO(%%i
  ) ELSE (
   SET "startline=%%i"
  )
 )
)

GOTO :eof
::
:: Write the header line to the next NEW destination file
::
:nextfname
SET "filename=%destdir%\%filecount%.log"
SET /a filecount+=1
IF EXIST %filename% GOTO nextfname
>>%filename% ECHO(%startline%
GOTO :eof