Имя пользователя:
Пароль:  
Помощь | Регистрация | Забыли пароль?  | Правила  

Компьютерный форум OSzone.net » Программирование, базы данных и автоматизация действий » Скриптовые языки администрирования Windows » CMD/BAT - [решено] разбить текстовый файл на несколько по условию

Ответить
Настройки темы
CMD/BAT - [решено] разбить текстовый файл на несколько по условию

Новый участник


Сообщения: 16
Благодарности: 0

Профиль | Отправить PM | Цитировать


Прошу помочь

Имеется текстовый файл следующего типа
# 1 Текст1
Ошибка1 текст
Ошибка2 текст
Ошибка3 текст
# 2 Текст2
Ошибка1 текст
Ошибка2 текст
Ошибка4 текст
# 3 Текст3
Ошибка2 текст
Ошибка4 текст
Ошибка5 текст
необходимо разделить на несколько текстовых файлов по следующему условию:
если в части текста которая начинается с символа # и до следующей # встречается фраза "Ошибка1" то всю эту часть текста скопировать в файл 1.txt и т.д.

Отправлено: 10:37, 21-01-2019

 

Аватара для YuS_2

Crazy


Contributor


Сообщения: 1167
Благодарности: 486

Профиль | Отправить PM | Цитировать


Цитата Rey71:
Перед отправкой отчета программа ФОМС проверяет отчет на наличие ошибок и формирует текстовый файл. (прикладываю образец файла с первыми двумя пациентами и ошибками по ним) »
Надо понимать так, что поведение программы, выдающей текстовый файл проверки отчета, изменить невозможно? Например, чтобы в итоговый файл, помимо самих ошибок, ещё выводился бы и код ошибки, по которому можно было бы их однозначно идентифицировать?

Цитата Rey71:
Необходимо разделить этот файл на несколько файлов которые будут группироваться по ошибкам чтобы раздать мед персоналу для исправления ошибок. »
Это надо понимать так:
В каждый отдельный файл, должны быть выведены только конкретные по типу ошибки, т.е. в каждом файле свои ошибки, привязанные к конкретному пациенту? Ну, нет смысла выводить в каждый файл весь список ошибок, если уж их требуется разделить. Иначе, проще разбить файл на определенное число пациентов, затем вывести их в файлы с полным содержимым ошибок по каждому пациенту...

Цитата Rey71:
как вариант можно создать файл с образцами основных ошибок и группировать по ним а если встретятся ошибки не существующие в файле образца ошибок то их собрать в отдельный файл. »
Да-да, правильно выше сказали, что только так, если нет возможности вывода вместе с ошибками и кодов этих ошибок...

-------
scio me nihil scire. Ѫ

Это сообщение посчитали полезным следующие участники:

Отправлено: 10:29, 23-01-2019 | #21



Для отключения данного рекламного блока вам необходимо зарегистрироваться или войти с учетной записью социальной сети.

Если же вы забыли свой пароль на форуме, то воспользуйтесь данной ссылкой для восстановления пароля.


Ветеран


Contributor


Сообщения: 2703
Благодарности: 1683

Профиль | Отправить PM | Цитировать


Как подсознательно чувствовал, кодировка файла 1251. Долой CMD.
ИМХО, в программе ФОМХ (совершенно с ней не знаком) заполняются некие поля.
Цитата Rey71:
Строка с ошибкой может быть как одинаковой целиком, например "У новорожденного не указан вес (не заполнено поле Weight)"
так и совпадающей только частью строки, например "Значения полей KPG и KSG не соответствуют справочнику KSG.DBF в отчетном периоде : KPG= 16, KSG=110"
где значения "KPG= 16, KSG=110" могут меняться в разных строках ошибок. »
Цитата Iska:
Оптимальный вариант, как я вижу — собирать виды ошибок сразу в виде регулярных выражений, для WSH или PoSH. »
ИМХО, это достаточно громоздко и не гибко.
Цитата alpap:
Rey71, не лучше ли это все было делать в excel »
Если заполняются поля и, кстати, они, похоже, поминаются в аварийном сообщении, то напрашивается решение:
формируем таблицу Excel по шаблону.
В первом столбце шаблона -заголовок секции (то, что начинается с #)
Во втором - ошибка без указания опознанного в строке сообщения поля - наверное, возможно и такое? Как, в принципе: когда имя поля в сообщении отсутствует, так и как упущении при создании Excel-шаблона: айтишник в атаку - дополняй шаблон, если надо.
В последующих - имена всех заполняемых полей. Сюда будут попадать сообщения, в котором помянуто поле в заголовке.
После импорта текстового файла в таблицу, созданную по шаблону, удаляем (скрываем?) столбцы, в которые ничего не попало, для лучшей читаемости.
Похоже, разный медперсонал отвечает за заполнение разных полей.
Флаг в руки! В фильтре таблицы каждый может указать отбор по своим непустым полям.
Вуаля!
ИМХО, довольно объёмная работа и для тестирования понадобится реальный файл.

Обычно я пытаюсь смотреть на инфу глазами конечного пользователя. Что он получает сейчас и что его в этом не устраивает? Сформулируйте, приведите примеры, прежде чем пытаться что-то делать, тыкая пальцем в небо.

Можно пойти по пути Iska, но немного не так.
Без Excel, например, в VBS, сформировать массив со списком полей в виде строки с разделителем для каждого пользователя и формировать столько файлов с копиями секций исходного файла, сколько элементов в этом массиве. Это более простое решение.

-------
Даже самая сложная проблема обязательно имеет простое, лёгкое для понимания, неправильное решение. Каждое решение плодит новые проблемы.


Последний раз редактировалось megaloman, 23-01-2019 в 11:49.

Это сообщение посчитали полезным следующие участники:

Отправлено: 11:03, 23-01-2019 | #22


Ветеран


Сообщения: 3806
Благодарности: 824

Профиль | Отправить PM | Цитировать


Теперь это уже немножко офтопик - мне было интересно решить задачу в первоначальной формулировке на powershell:

Код: Выделить весь код
$errors = @{}

switch -Regex -CaseSensitive -File 'errors.log' {
    '^#.*' {     
        $section = [System.Collections.Generic.List[String]]$_
        continue
    }
    default {
        $section.Add($_)
        $errors[$_] += [System.Collections.Generic.List[String]]$section
    }
}

$errors.Values | .{begin{$n=0} process{$n++; Add-Content -Path "$n.txt" -Value $_ }}
Это сообщение посчитали полезным следующие участники:

Отправлено: 12:41, 23-01-2019 | #23


Аватара для YuS_2

Crazy


Contributor


Сообщения: 1167
Благодарности: 486

Профиль | Отправить PM | Цитировать


Ну тогда и я на powershell со своей идефикс, что выводить все ошибки по каждому пациенту в разные файлы иррационально.
Принцип:
для каждой ошибки свой файл, если есть ошибка с привязкой к пациенту, то выводим такую ошибку в определенный для неё файл:
Код: Выделить весь код
$fle = 'obraz.txt'
$err_out = 'error_out.txt'

gc $fle -enc default|%{$flg,$arr,$err=$true,@(),@()}{
	if ($_ -match '#\s*\d+'){$name = $_} else {
		$tmp = $_
		for ($i=0;$i -lt $arr.count;$i++){
			if ($tmp -match $arr[$i]){
				$name,$tmp|out-file "$($i+1).txt" -enc default -app
				$flg = $false
			}
		}
		if ($flg){
			$arr += ($tmp -replace '^([^:\(,]*).*','$1')
			$name,$tmp|out-file "$($i+1).txt" -enc default -app
			$err+=$tmp
		}
		$flg=$true
	}
}
$err|sc $err_out -enc default
бонусом выводится перечень уникальных ошибок...

-------
scio me nihil scire. Ѫ

Это сообщение посчитали полезным следующие участники:

Отправлено: 13:10, 23-01-2019 | #24


Ветеран


Contributor


Сообщения: 2703
Благодарности: 1683

Профиль | Отправить PM | Цитировать


Rey71,
VBS. Немного оффтоп, считаю, что ошибка занимает всю строку целиком. Для удобства вывел ошибку в заголовок сформированного файла.
Отельным файлом с номером 0000 выдал список ошибок и номера файла, где они фигурируют
Код: Выделить весь код
FileIn = "Z:\Box_In\Errors\исходный файл.TXT"
' FileIn = "Z:\Box_In\Errors\obraz.TXT"
BoxOut = "Z:\Box_In\Errors"

Set FSO = CreateObject("Scripting.FileSystemObject")

On Error Resume Next
Set fIn = FSO.OpenTextFile(FileIn, 1, False)

If Err.Number <> 0 Then
    MsgBox "Ошибка при открытии" + vbCrLf + FileIn + vbCrLf + vbCrLf + Err.Description
    WScript.Quit 2
End If
On Error GoTo 0

Alls = fIn.ReadAll
fIn.Close

MasAll = Split(Alls, vbCrLf)
MasN = Split(Alls, "#")

A0 = LBound(MasAll)
AN = UBound(MasAll)

N0 = LBound(MasN)
NN = UBound(MasN)

Set Alls = Nothing
ReDim MasErr(AN)
ie = A0 - 1

For Each s In MasAll
    If Not Len(Replace(s, " ", "")) = 0 Then
        If Not Mid(s, 1, 1) = "#" Then
            If ie = A0 - 1 Then
                ie = A0
                MasErr(ie) = s
            Else
                L = 0
                For i = A0 To ie
                    If s = MasErr(i) Then
                        L = 1
                        Exit For
                    End If
                Next
                If L = 0 Then
                    ie = ie + 1
                    MasErr(ie) = s
                End If
            End If
        End If
    End If
Next

DNow = Date
sNow = Mid(CStr(Year(DNow)), 3, 2) + Mid(CStr(Month(DNow) + 100), 2, 2) + Mid(CStr(Day(DNow) + 100), 2, 2)
DNow = Time
sNow = sNow + Mid(CStr(Hour(DNow) + 100), 2, 2) + Mid(CStr(Minute(DNow) + 100), 2, 2) + Mid(CStr(Second(DNow) + 100), 2, 2)

nFile = 10000

On Error Resume Next
Set fErr = FSO.CreateTextFile(BoxOut + "\" + sNow + "_" + Mid(CStr(nFile), 2) + ".txt", True)

If Err.Number <> 0 Then
    MsgBox "Ошибка при создании" + vbCrLf + vbCrLf + BoxOut + "\" + sNow + "_" + Mid(CStr(nFile), 2) + ".txt" + vbCrLf + Err.Description
    WScript.Quit 2
End If

For Each s In MasErr
    nFile = nFile + 1
    If nFile - 10000 > ie + 1 - A0 Then Exit For
    On Error Resume Next
    Set fOut = FSO.CreateTextFile(BoxOut + "\" + sNow + "_" + Mid(CStr(nFile), 2) + ".txt", True)

    If Err.Number <> 0 Then
        MsgBox "Ошибка при создании" + vbCrLf + vbCrLf + BoxOut + "\" + sNow + "_" + Mid(CStr(nFile), 2) + ".txt" + vbCrLf + Err.Description
        WScript.Quit 2
    End If
    fErr.WriteLine Mid(CStr(nFile), 2) + " " + s
    fOut.Write "=== Ошибка " + s + vbCrLf + vbCrLf

    On Error GoTo 0

    For Each block In MasN
        If Not Len(Replace(Replace(block, vbCrLf, ""), " ", "")) = 0 Then
            If InStr(1, block, s) <> 0 Then
                    fOut.Write "#" + block
            End If
        End If
    Next
    fOut.Close
Next
fErr.Close
MsgBox "Скрипт завершен"

-------
Даже самая сложная проблема обязательно имеет простое, лёгкое для понимания, неправильное решение. Каждое решение плодит новые проблемы.


Последний раз редактировалось megaloman, 23-01-2019 в 21:27.

Это сообщение посчитали полезным следующие участники:

Отправлено: 19:42, 23-01-2019 | #25


Новый участник


Сообщения: 16
Благодарности: 0

Профиль | Отправить PM | Цитировать


Всем огромное спасибо.
Понял что с наскока решить не получится.
Буду думать над правильной постановкой задачи.

Отправлено: 06:16, 24-01-2019 | #26


Аватара для YuS_2

Crazy


Contributor


Сообщения: 1167
Благодарности: 486

Профиль | Отправить PM | Цитировать


Цитата Rey71:
Понял что с наскока решить не получится.
Буду думать над правильной постановкой задачи. »
Решить-то, как раз можно... вопрос именно только в постановке задачи.
Что в конечном итоге требуется получить?
Особенно, желательно описать подробнее это:
Цитата Rey71:
несколько файлов которые будут группироваться по ошибкам чтобы раздать мед персоналу для исправления ошибок. »
т.е. как именно необходимо группировать ошибки? Для одного человека несколько пациентов со всеми ошибками или же для одного человека - только один тип ошибки?
то бишь:
1. Один файл - один тип ошибки, но по разным пациентам, у которых этот тип ошибки присутствует.
2. Один файл - несколько (сколько именно?) пациентов, причем со всеми ошибками по каждому, отобранному пациенту.
3. ... ?
Третьего варианта, лично я не вижу, т.к. при нахождении одного типа ошибки по одному пациенту, выводить все ошибки привязанные к этому пациенту в отдельный файл - не имеет смысл, т.к. не будет никакой упорядоченности, да и собственно, вообще никакого алгоритма отбора информации для вывода в разные файлы, в этом случае тоже не будет.

-------
scio me nihil scire. Ѫ


Отправлено: 09:53, 24-01-2019 | #27


Deadooshka


Сообщения: 2481
Благодарности: 670

Профиль | Отправить PM | Цитировать


Надо вычислять какой-то идентификатор строки ошибки. Например, удалить весь известный динамический контент в строке ошибки, (или всё, кроме кириллицы), привести к одному регистру, вычислить md5 от того, что осталось. Это будет ключ для группировки по ошибке (по файлам, или поле в БД).

Отправлено: 11:52, 24-01-2019 | #28


Ветеран


Сообщения: 3806
Благодарности: 824

Профиль | Отправить PM | Цитировать


Sham, если понимать, что такое хэш-таблица, или представлять как устроены БД, то становится очевидным, что все эти велосипеды изобретены и реализованы до вас
Это сообщение посчитали полезным следующие участники:

Отправлено: 13:03, 24-01-2019 | #29



Компьютерный форум OSzone.net » Программирование, базы данных и автоматизация действий » Скриптовые языки администрирования Windows » CMD/BAT - [решено] разбить текстовый файл на несколько по условию

Участник сейчас на форуме Участник сейчас на форуме Участник вне форума Участник вне форума Автор темы Автор темы Шапка темы Сообщение прикреплено

Похожие темы
Название темы Автор Информация о форуме Ответов Последнее сообщение
CMD/BAT - [решено] Создать несколько файлов из одного по условию Rey71 Скриптовые языки администрирования Windows 9 28-04-2018 08:13
CMD/BAT - [решено] разбить файл на много файлов по шаблону и каждый файл положить в папку Mezolick Скриптовые языки администрирования Windows 3 03-02-2017 08:38
CMD/BAT - [решено] Как построчно разбить текстовый файл на текстовые файлы содержащие одну строку binwatch@vk Скриптовые языки администрирования Windows 3 09-09-2012 19:59
CMD/BAT - Разбить текстовый файл на части определенного размера. kamcom88 Скриптовые языки администрирования Windows 0 22-03-2012 12:23
CMD/BAT - Как разбить текстовый файл на куски определенного размера? helik Скриптовые языки администрирования Windows 7 16-11-2011 06:35




 
Переход