-1

我在批处理编程方面不是很有经验。我已经将各种代码拼凑在一起,但它也不能像我想要的那样工作。

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

    START STRING 1234
    NAME1 ADRESS1 ETC
    NAME2 ADRESS2 ETC
    NAME3 ADRESS3 ETC

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

    START STRING
    NAME ADRESS ETC

这是到目前为止的代码。它有点工作..除非目录中一次有一个以上的日志文件,否则我最终会得到一些条目,其中只有两个 START STRING,我需要避免。换句话说,我需要它分别浏览每个日志文件,而不是像我假设的那样,将所有日志文件视为一个单独的大文本文件。

    @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

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

4

2 回答 2

1

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

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

@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"
)

限制:

  • 行必须以<CR><LF>(Windows 样式) 结尾,而不是<LF>(unix 样式)
  • 行不得超过 1021 字节(不包括行终止符)
  • 尾随控制字符将从行中删除。

根据评论,上述解决方案不符合OP的需求


编辑:根据 OP 评论中的细化要求尝试 2(未经测试)

空行将被忽略 - 可能是一件好事。

该代码旨在鲁棒。它应该处理字符串中的任何字符,包括以;(或任何其他字符)开头的行,以及包含!. 这就是奇数 FOR /F 选项字符串和延迟扩展切换的原因。

行长度限制为大约 8191 字节。

@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
    )
  )
)
于 2013-06-07T11:46:37.027 回答
0
@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

这应该做你想要的 - IIUC,从.log源中的每个文件,在目标中创建一个包含 2 行的文件 - 对应源日志文件的起始行之后的名称行。(好吧,如果这不是你想要的,这就是这个例程要做的......)

  • 它处理源目录中的每个文件名,应用于%%f.
  • 在每个新文件名处,清除startline
  • 将第一行的内容分配给startline
  • 对于剩余的每一行,
    • 在目标中设置filename一个新的文件名并将起始行写入它
    • 将名称行输出%%i到生成的文件名中。

请注意,当ENABLEDELAYEDEXPANSION它在!filename!filenameFOR...%%i...

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

于 2013-06-07T14:27:00.307 回答