2013-06-07 3 views
-1

Я не очень опытен в пакетном программировании. Я вроде как ковылял разные кусочки кода, но это не совсем так, как я этого хочу.Анализ нескольких текстовых файлов и их восстановление до заданного шаблона

В этом проблема. Файлы журналов создаются в каталоге. Некоторые из них представляют собой несколько записей. Все они следуют определенной схеме. 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 

Я уверен, что есть более умный способ сделать это, но это насколько я получил. Удивление, могу ли я просто сопоставить стартовую строку и как-то удалить ее, не удаляя эту первую строку или, желательно, избегая двойного начала строки.

+0

Если файл журнала содержит более одного имени, которое вы хотите сохранить? Первый? Последний? – Aacini

+0

Исходные имена файлов журналов не имеют большого значения, поскольку после их анализа они будут удалены. Неважно, какие файлы вызывают, как только они были проанализированы. В этом примере их просто назовут 2.log, 3.log и т. Д. – user2463125

+0

По моему скромному мнению, если вы измените свои требования по запросу в течение некоторого времени после размещения вопроса, вы должны подождать гораздо больше времени, прежде чем закрыть вопрос как " решено "; в противном случае вы пренебрегаете людьми, которые сначала читают ваш вопрос, когда он был неполным и не может быть разрешен ... :( – Aacini

ответ

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 к новому имени файла в пункт назначения и записывает StartLine в это
    • выводит имя строки в %%i к сгенерировано имя файла.

Обратите внимание, что ENABLEDELAYEDEXPANSION позволяет !filename!, чтобы относится к содержанию filename, как он меняется в контексте FOR...%%i...

Процедура :nextfilename находится в своем собственном контексте, так что% переменная% используется в его более знакомом смысле. Процедура просто устанавливает имя от filecount и увеличивает filecount, проверяет, существует ли файл уже и повторяется до тех пор, пока не будет найдено совершенно новое имя файла. Затем строка заголовка записывается в это имя файла.

+0

Фантастично! Это сработало чудеса. – user2463125

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, основанный на комментарий


EDIT: Попытка 2 на основе уточненных требований в commment ФП в (непроверенные)

Blank линии будут проигнорированы - вероятно, хорошо.

Код цели - грудь. Он должен обрабатывать любые символы в строке, включая строки, начинающиеся с ; (или любого другого символа), и строки, содержащие !. В этом причина нечетной строки опций 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 
    ) 
) 
) 
+0

А, прошу прощения, что мое описание было немного расплывчатым. Если в файле есть 3 имени, Мне нужно создать три отдельных файла, каждый из которых начинается с START STRING в одной строке и имя на следующей строке. Проблема возникает, когда в каталоге говорят, что есть два файла журнала. Затем он рассматривает их как один большой файл, что означает START STRING появится дважды в одном из файлов, так как моя программа всегда добавляет первую строку к каждому новому файлу. По какой-то причине он рассматривает несколько файлов как один большой текстовый файл, что означает, что начальная строка появляется несколько раз. – user2463125

+0

@ user2463125 - ОК, я думаю, что понимаю ваши требования сейчас. Посмотрите мою вторую попытку в пересмотренном ответе. – dbenham

Смежные вопросы