Read by line 2

Обсуждение программ nnCron и nnCron LITE

Read by line 2

Postby VoidVolker » Fri, 07 Aug 2015, 12:42

Новые плюшки: предзагрузка файла в память и освобождение памяти после работы с файлом, счетчик строк, работа со строками, поддержка любых делителей строк (unix, osx и вообще любая строка).
Требования: исправление ошибки в SEARCHviewtopic.php?f=5&t=13236
Скачать read-by-line.spf
Подробное описание тут: viewtopic.php?f=23&t=9583&p=20042#p20042
95% вопросов уже обсуждались на форуме или ответы на них есть в мануале.        nnCron 1.93 b15.exe
Как правильно задавать вопросы.
User avatar
VoidVolker
Site Admin
 
Posts: 2898
Joined: Tue, 25 Apr 2006, 17:56

Re: Read by line 2 - beta

Postby VoidVolker » Fri, 07 Aug 2015, 13:28

Файл в список:
Code: Select all
: FILE2LIST   \ ( a u list -- )
    -ROT
    FOR-FILE-LINES
        DUP FOUND-LINE ROT LIST!
    ;FOR-FILE-LINES
    DROP
;


Подсчет строк в файле:
Code: Select all
0 S" path\to\file" FOR-FILE-LINES
    DROP LINE-NUMBER
;FOR-FILE-LINES


Разделение строки или файла на подстроки:
Code: Select all
: SPLIT   \ ( a1 u1 a2 u2 -- list )
    LE-GET 2>R
    LE-SET
    STRING-LIST -ROT
    FOR-LINES
        DUP FOUND-LINE ROT LIST!
    ;FOR-LINES
    2R> LE-SET
;

: FSPLIT   \ ( a1 u1 a2 u2 -- list )
    LE-GET 2>R
    LE-SET
    STRING-LIST -ROT
    FOR-FILE-LINES
        DUP FOUND-LINE ROT LIST!
    ;FOR-FILE-LINES
    2R> LE-SET
;

Code: Select all
: list. LIST( NODE@ TYPE CR )LIST ;
S" ab cd efg hkl mno pq r s"  S"  " SPLIT list.
95% вопросов уже обсуждались на форуме или ответы на них есть в мануале.        nnCron 1.93 b15.exe
Как правильно задавать вопросы.
User avatar
VoidVolker
Site Admin
 
Posts: 2898
Joined: Tue, 25 Apr 2006, 17:56

Re: Read by line 2

Postby VoidVolker » Tue, 11 Aug 2015, 15:32

Ап! Загрузил на сервер и добавил описание. Как всегда приветствуются отзывы и предложения по функционалу :)
95% вопросов уже обсуждались на форуме или ответы на них есть в мануале.        nnCron 1.93 b15.exe
Как правильно задавать вопросы.
User avatar
VoidVolker
Site Admin
 
Posts: 2898
Joined: Tue, 25 Apr 2006, 17:56

Re: Read by line 2

Postby spronkin » Wed, 28 Oct 2015, 02:47

Здравствуйте! Хотелось бы увидеть более детальный description пользовательских переменных в файле read-by-line.spf.
leU
leA
LINE-NUMBER
Lu
Lc
fEND
а также узнать отличие выхода RBL-EXIT от LINE-EXIT.

Я понял, что теперь к FOUND-LINE добавилась переменная LINE-NUMBER, обозначающая номер строки в цикле.

У меня возникла проблема с установкой разделителя строк вручную или получением разделителя строк из файла.
Задача - хочу вывести в цикле LINE-NUMBER текущей строки. Если файл с WIN-разделителями, action короткий, проблем нет:
Code: Select all
Action:
    READ-BY-LINE: "c:\nncron\adph.txt"
    MSG: "%LINE-NUMBER%"
    ;READ-BY-LINE


Если же файл с UNIX-разделителями строк 0x0A, пытаюсь выполнить ту же задачу так:
Code: Select all
Action:
    READ-BY-LINE: "c:\nncron\adph.txt"
    LE-UNIX
    MSG: "%LINE-NUMBER%"
    ;READ-BY-LINE


Code: Select all
Action:
    LE-GET 2>R
    LE-SET
    STRING-LIST -ROT
    READ-BY-LINE: "c:\nncron\adph.txt"
    MSG: "%LINE-NUMBER%"
    ;READ-BY-LINE
    2R> LE-SET


В первом случае он не распознает разделитель строк и выводит весь текст в файле как одну строку (MSG: "1" и все). Во втором случае я пытаюсь считать текущий разделить из строки файла, но Action выдает синтаксическую ошибку на строке, содержащей слово STRING-LIST (кстати где оно должно определяться?) и тут я не уверен, что я делаю правильно.
User avatar
spronkin
 
Posts: 86
Joined: Sun, 15 Jan 2012, 13:56

Re: Read by line 2

Postby elos » Wed, 28 Oct 2015, 09:41

Разве чтение секции EXPORT плагина не разъясняет всё?

Также перечитываем описание плагина, где есть строка:
Изменять разделитель строк следует перед циклом. Допускается изменение разделителя строк внутри цикла, но после окончания цикла будет восстановлен исходный разделитель строк.


"LE-" - "line end" , соответственно LE-UNIX - это конец строки в unix-стиле
"RBL-EXIT" - "read by line exit" - относится к циклу READ-BY-LINE:
"LINE-EXIT" - относится к циклу FOR-LINES:
elos
 
Posts: 665
Joined: Tue, 25 Apr 2006, 11:15

Re: Read by line 2

Postby VoidVolker » Wed, 28 Oct 2015, 13:11

spronkin wrote:Здравствуйте! Хотелось бы увидеть более детальный description пользовательских переменных в файле read-by-line.spf. leU leA LINE-NUMBER Lu Lc fEND
leU leA Lu Lc fEND данные слова не являются пользвоательскими переменными.
spronkin wrote:а также узнать отличие выхода RBL-EXIT от LINE-EXIT.

Для выхода в разных циклах - по названиям циклов. По факту - синонимы. Для обратной совместимости со старым кодом, применять каждое в своем цикле - для улучшения читаемости, а так же на случай внутренних изменений в циклах.
RBL работает только с переводами строк windows формата (0x0D0A). Для работы с другими разделителями строк следует использовать циклы FOR-LINES и FOR-FILE-LINES.
95% вопросов уже обсуждались на форуме или ответы на них есть в мануале.        nnCron 1.93 b15.exe
Как правильно задавать вопросы.
User avatar
VoidVolker
Site Admin
 
Posts: 2898
Joined: Tue, 25 Apr 2006, 17:56

Re: Read by line 2

Postby VoidVolker » Wed, 28 Oct 2015, 13:35

spronkin wrote:
Code: Select all
Action:
    LE-GET 2>R
    LE-SET
    STRING-LIST -ROT
    READ-BY-LINE: "c:\nncron\adph.txt"
    MSG: "%LINE-NUMBER%"
    ;READ-BY-LINE
    2R> LE-SET


В первом случае он не распознает разделитель строк и выводит весь текст в файле как одну строку (MSG: "1" и все). Во втором случае я пытаюсь считать текущий разделить из строки файла, но Action выдает синтаксическую ошибку на строке, содержащей слово STRING-LIST (кстати где оно должно определяться?) и тут я не уверен, что я делаю правильно.

Code: Select all
LE-GET 2>R
LE-SET

Данный код уже разрушит стек, т.к., после первой строки на стеке пусто. А слову LE-SET нужна строка.
STRING-LIST - вообще из другого плагина. И к настройками данного плагина отношения не имеет.
Код явно из слова FSPLIT - оно загружает файл, разрезает его на строки по разделителю и возвращает список строк. Просто пример в вакууме. Не следует вырывать код из контекста.

spronkin wrote:У меня возникла проблема с установкой разделителя строк вручную или получением разделителя строк из файла.
Задача - хочу вывести в цикле LINE-NUMBER текущей строки. Если файл с WIN-разделителями, action короткий, проблем нет:


Code: Select all
S" strings_separator.txt" FILE LE-SET
S" any_file.txt" FOR-FILE-LINES
    LINE-NUMBER . CR
;FOR-FILE-LINES
95% вопросов уже обсуждались на форуме или ответы на них есть в мануале.        nnCron 1.93 b15.exe
Как правильно задавать вопросы.
User avatar
VoidVolker
Site Admin
 
Posts: 2898
Joined: Tue, 25 Apr 2006, 17:56

Re: Read by line 2

Postby Serjo » Fri, 30 Oct 2015, 16:04

Всем доброго здравия
Обнаружилась проблема в цикле FOR-FILE-LINES. Заключается в следующем:
Когда слово используется в бесконечном цикле BEGIN ... AGAIN, то через какое-то время (примерно после 30-ти циклов) выдает ошибку: внутренняя ошибка. Error # -1073741819. В цикле READ-BY-LINE такого не наблюдается, но там и переноса строки в utf8 нет.
Когда составил задачу без цикла, с включением каждую минуту, то всё отрабатывает нормально: вот уже почти сутки работает без ошибок. (Количество включений более 1000)

PS WinXP SP3 x32
PPS Если нужна дополнительная инфа по возникшей ошибке, то выложу, говорите что нужно
Serjo
 
Posts: 7
Joined: Fri, 13 Dec 2013, 20:08

Re: Read by line 2

Postby VoidVolker » Fri, 30 Oct 2015, 17:22

Нужен код.
95% вопросов уже обсуждались на форуме или ответы на них есть в мануале.        nnCron 1.93 b15.exe
Как правильно задавать вопросы.
User avatar
VoidVolker
Site Admin
 
Posts: 2898
Joined: Tue, 25 Apr 2006, 17:56

Re: Read by line 2

Postby Serjo » Sun, 01 Nov 2015, 23:06

Задачу упростил. Не глючит значительно дольше. Но глюк всё равно словил.
Описание: скрипт заходит на вэбинтерфейс спутникового ресивера (ITGate - клон DreamBox), достает нужную инфу: уровень сигнала, качество, кол-во ошибок в потоке и пр.
Вот задача:
Code: Select all
#( глючная_задача

CREATE temp_str_level_ITG 256 ALLOT
VARIABLE SNR
VARIABLE AGC
VARIABLE BER
VARIABLE Счетчик_Цикла_Уровень_ITG

\ 1) Адрес вэб морды
: Опрашиваемый_Ресивер S" http://192.168.0.107/xml/streaminfo" ;

\ 2) временный файл с информацией из вэбморды
: Инфо_Файл_ITG_GET S" C:\temp\test_GET_status_ITG.txt" ;

\ 3) файл лога с инфой с уровнем
: Лог_Файл_Уровень_Сигнала_ITG S" F:\логи\уровень_сигнала_ITG.log" ;

\ NoActive
SingleInstance
AsLoggedUser
Time: * * * * * *
Action:
1 Счетчик_Цикла_Уровень_ITG !

S" Ресивер " Опрашиваемый_Ресивер S+ Лог_Файл_Уровень_Сигнала_ITG FAPPEND

BEGIN
   
    \ === отладочная инфа на консоль ===============
        S" %hh%:%mm%:%ss% Лог Работы с вэбмордой ITG" EVAL-SUBST TYPE CR
        S" Опрашивем ресивер = " TYPE Опрашиваемый_Ресивер TYPE CR
        S" %crlf%Номер опроса = %Счетчик_Цикла_Уровень_ITG @%" EVAL-SUBST 2DUP TYPE CR Лог_Файл_Уровень_Сигнала_ITG FAPPEND
        crlf Лог_Файл_Уровень_Сигнала_ITG FAPPEND
    \ === отладочная инфа на консоль ===============

    \ 1) достаем инфу infostream и пишем её в файл
    Опрашиваемый_Ресивер HTTP-GET 0=
    IF 
        S" Ресивер " TYPE Опрашиваемый_Ресивер TYPE S"  - ответ получен" TYPE CR
    ELSE
        2DROP
        S" Ресивер не ответил. Выходим из задачи." TYPE CR
        EXIT
    THEN

    \ 2) Пишем инфу из вэбморды во временный файл
    Инфо_Файл_ITG_GET FWRITE
   
    \ 3) Выводим на консоль интересющую нас инфу из приготовленного файла и пишем в свой лог
   
   
    \ 3.2. Включаем строковый цикл, отбираем нужные строки
   
    LE-UNIX Инфо_Файл_ITG_GET
    FOR-FILE-LINES
        \ 3.2.1 - строка Service Name (канал)
        FOUND-LINE S" /<name>/i" RE-MATCH
            IF
                \ строка вида <name>СПОРТ НТВ-ПЛЮС</name>
                \ получаем из этой строки имя канала
                S" Канал         = " Лог_Файл_Уровень_Сигнала_ITG FAPPEND
                FOUND-LINE 7 /STRING 7 - 0 MAX
                UTF8>UNICODE UNICODE>S 
                Лог_Файл_Уровень_Сигнала_ITG FAPPEND
                crlf Лог_Файл_Уровень_Сигнала_ITG FAPPEND
            THEN
        \ 3.2.2 - строка Frequency (транспондер)
        \
        FOUND-LINE S" /<frequency>/i" RE-MATCH
            IF 
                \ строка вида <frequency>12322</frequency>
                S" Частота       = " Лог_Файл_Уровень_Сигнала_ITG FAPPEND
                FOUND-LINE 11 /STRING 12 - 0 MAX
                Лог_Файл_Уровень_Сигнала_ITG FAPPEND
                crlf Лог_Файл_Уровень_Сигнала_ITG FAPPEND
            THEN
        \ 3.2.3 - строка SNR (уровень)
        FOUND-LINE S" /<SNR>/i" RE-MATCH
            IF 
                \ строка вида <snr>85%</snr>
                S" Уровень SNR   = " Лог_Файл_Уровень_Сигнала_ITG FAPPEND
                FOUND-LINE 5 /STRING 7 - 0 MAX
                2DUP S>NUM SNR !
                Лог_Файл_Уровень_Сигнала_ITG FAPPEND
                crlf Лог_Файл_Уровень_Сигнала_ITG FAPPEND
               
            THEN
        \ 3.2.4 - строка AGC (качество)
        FOUND-LINE S" /<AGC>/i" RE-MATCH
            IF 
                \ строка вида <agc>72%</agc>
                S" Качество AGC  = " Лог_Файл_Уровень_Сигнала_ITG FAPPEND
                FOUND-LINE 5 /STRING 7 - 0 MAX
                2DUP S>NUM AGC !
                Лог_Файл_Уровень_Сигнала_ITG FAPPEND
                crlf Лог_Файл_Уровень_Сигнала_ITG FAPPEND
            THEN
        \ 3.2.5 - строка BER (кол-во ошибок)
        \ строка вида <ber>0</ber>
        FOUND-LINE S" /<BER>/i" RE-MATCH
            \ пока не делаем числовое значение т.к. значение предствалено в экспоненциальной форме 1E-10
            \ Поэтому делаем проверку наличия буквы E в значении и если она присутствует, то это значит, что и ошибки присутствуют
            IF
                FOUND-LINE 5 /STRING 6 - 0 MAX
                S" /E/i" RE-MATCH
                IF 
                    S" ОШИБКИ В ПОТОКЕ!" Лог_Файл_Уровень_Сигнала_ITG FAPPEND
                    -1 BER !
                ELSE
                    S" Ошибок в потоке нет" Лог_Файл_Уровень_Сигнала_ITG FAPPEND
                    crlf Лог_Файл_Уровень_Сигнала_ITG FAPPEND
                    0 BER !
                THEN
                FOUND-LINE 5 /STRING 6 - 0 MAX
                Лог_Файл_Уровень_Сигнала_ITG FAPPEND
                crlf Лог_Файл_Уровень_Сигнала_ITG FAPPEND
            THEN
    ;FOR-FILE-LINES

    \ ================ отладка ========================================
    S" Стоп номер = " TYPE Счетчик_Цикла_Уровень_ITG @ N>S TYPE CR
    \ =================================================================
    \ 4) Проводим анализ полученных данных
    \ BER AGC SNR и пр.
   
    30000 PAUSE  \ пауза варируется в завсисмости от уровня сигнала SAT
    Счетчик_Цикла_Уровень_ITG @ 1+ Счетчик_Цикла_Уровень_ITG !
AGAIN

)#
Serjo
 
Posts: 7
Joined: Fri, 13 Dec 2013, 20:08

Re: Read by line 2

Postby Serjo » Thu, 05 Nov 2015, 16:20

Так что, совсем :rolleyes: всё плохо? :)
Serjo
 
Posts: 7
Joined: Fri, 13 Dec 2013, 20:08

Re: Read by line 2

Postby elos » Thu, 05 Nov 2015, 16:59

Не вникая в код (а в такую "портянку" тяжело вникать), но видя волшебное S+ из ~nn/lib/az.f...
Code: Select all
: S+ ( a1 u1 a2 u2 -- a3 u3)
    2OVER NIP OVER + 1+ ALLOCATE THROW >R
    2SWAP R@ ZPLACE
    R@ +ZPLACE R> ASCIIZ>   
;

Если использовать в цикле и не освобождать память самому - можно влететь... Но у тебя вроде вне цикла и один раз употребляется.

Остаётся строчка "Time: * * * * * *". Если не путаю, то запуск задачи будет каждую минуту - это почти цикл для твоего употребления. И если каждую минуту от памяти откусывать примерно по 50 байт твоего строкового "Опрашиваемый_Ресивер" в сумме со словом "Ресивер", то неизвестно как поведёт себя менеджер памяти винды... Хотя с окончанием задачи память должна освобождаться. Да и цикл ты убирал...

Куски кода в цикл пробовал загонять с вручную задаваемыми строками?

P.S. У меня есть на биллинговой машине с W2K задача на VFP9 с предполагаемой утечкой памяти при частой обработке мелких текстовых файлов команд (максимально было 200 строк на моей памяти, а так 1-5) - так она в итоге вешает машину при полутора гигах свободной памяти, опустившись вниз на 200 мегабайт от исходного размера после загрузки самой машины. И часто - это не более 5 раз в день.

Кстати, где фрагмент 3.1в нижележащем коде?
Code: Select all
    \ 3) Выводим на консоль интересющую нас инфу из приготовленного файла и пишем в свой лог
   
   
    \ 3.2. Включаем строковый цикл, отбираем нужные строки
elos
 
Posts: 665
Joined: Tue, 25 Apr 2006, 11:15

Re: Read by line 2

Postby Serjo » Thu, 05 Nov 2015, 22:50

elos wrote:Не вникая в код (а в такую "портянку" тяжело вникать)

Извиняюсь за "портяночный" вид - я не профи, поэтому, возможно, вид скрипта "плохочитабельный". :mrgreen:
elos wrote:Если использовать S+ в цикле и не освобождать память самому - можно влететь... Но у тебя вроде вне цикла и один раз употребляется.

Это уже просмотрел, где то на форуме уже предупреждали о таком свойстве S+
elos wrote:Остаётся строчка "Time: * * * * * *". Если не путаю, то запуск задачи будет каждую минуту - это почти цикл для твоего употребления. И если каждую минуту от памяти откусывать примерно по 50 байт твоего строкового "Опрашиваемый_Ресивер" в сумме со словом "Ресивер", то неизвестно как поведёт себя менеджер памяти винды... Хотя с окончанием задачи память должна освобождаться. Да и цикл ты убирал...

У меня опрос ресивера происходит от 10 сек до 5 минут в зависимости от уровня принимаемого сигнала. Поэтому сделан цикл. А выход из задачи сделан в случае, если ресивер не отвечает на запросы: в случае глюков, зависаний и пр. проблем на стороне ресивера.
Но это не суть. Главное, что слово READ-BY-LINE в аналогичной задаче (где виндовый перенос строк) отрабатывает нормально. Но в этом слове нет плюшки LE-UNIX. И в этом случае у меня весь файл становиться одной большой строкой, с которой может и можно работать, но как-то не фэйшуйно :)
Потому я и подумал, что дело в цикле FOR-FILE-LINES
Serjo
 
Posts: 7
Joined: Fri, 13 Dec 2013, 20:08

Re: Read by line 2

Postby Serjo » Mon, 09 Nov 2015, 17:13

Переустановил крон. Поставил сборку nncron193b13. Всё нормально отрабатывает. Так что FOR-FILE-LINES в порядке.
Еще раз спасибо за плагин и развитие программы. :rock:
Serjo
 
Posts: 7
Joined: Fri, 13 Dec 2013, 20:08

Re: Read by line 2

Postby elos » Mon, 09 Nov 2015, 21:07

А какая ж версия до этого была?
elos
 
Posts: 665
Joined: Tue, 25 Apr 2006, 11:15

Next

Return to nnCron forum (Russian)

Who is online

Users browsing this forum: No registered users and 1 guest