Автоматическое обнаружение / синтаксический анализ таблиц в Python

Я должен проанализировать большую часть вывода CLI UNIX, в большинстве случаев вывод представляет собой таблицу, но они всегда различаются по количеству столбцов / формату... и т. Д., Я должен продолжать изменять свой код синтаксического анализа для каждой команды. TxtFSM облегчает жизнь, но мне все еще нужно написать шаблон.

Я хотел бы написать сценарий, который будет автоматически определять вывод CLI, и когда он обнаруживает таблицу, он будет анализировать его. Интересно, как новичку в мире парсинга, насколько это сложно / сложно? Если кто-нибудь видел подобные усилия / проекты раньше?

Меня всегда смущают сложные темы разбора, такие как BNF, YACC... и т. Д.

Спасибо

1 ответ

Вот как вы можете разобрать df вывод в таблицу с использованием Perl и Marpa::R2

сценарий (~ обозначает лексические правила):

use 5.010;
use strict;
use warnings;

use Data::Dumper;
$Data::Dumper::Indent = 1;
$Data::Dumper::Terse = 1;
$Data::Dumper::Deepcopy = 1;

use Marpa::R2;

my $g = Marpa::R2::Scanless::G->new( { source => \(<<'END_OF_SOURCE'),

    :default ::= action => [ name, value]
    lexeme default = action => [ name, value] latm => 1

        table       ::= (header [\n]) rows
        header      ~ 'Filesystem      Size  Used Avail Use% Mounted on'
        rows        ::= row+ separator => [\n]
        row         ::= fs size used avail use_percent mounted_on

        fs          ~ [A-Z] ':'
        size        ~ digits 'G'
        used        ~ digits 'G'
        avail       ~ digits 'G'
        use_percent ~ digits '%'
        mounted_on  ~ [/\w]+

        digits ~ [\d\.]+

    :discard ~ whitespace
    whitespace ~ [\s]+

END_OF_SOURCE
} );

my $input = <<EOI;
Filesystem      Size  Used Avail Use% Mounted on
C:              101G   90G   11G  90% /cygdrive/c
D:              366G  230G  137G  63% /cygdrive/d
E:               38G  9.6G   28G  26% /cygdrive/e
EOI

say Dumper $g->parse( \$input, { trace_terminals => 0 } ); exit;

выход:

\[
        'table',
        [
            'rows',
            [
                'row',
                [
                    'fs',
                    'C:'
                ],
                [
                    'size',
                    '101G'
                ],
                [
                    'used',
                    '90G'
                ],
                [
                    'avail',
                    '11G'
                ],
                [
                    'use_percent',
                    '90%'
                ],
                [
                    'mounted_on',
                    '/cygdrive/c'
                ]
            ],
            [
                'row',
                [
                    'fs',
                    'D:'
                ],
                [
                    'size',
                    '366G'
                ],
                [
                    'used',
                    '230G'
                ],
                [
                    'avail',
                    '137G'
                ],
                [
                    'use_percent',
                    '63%'
                ],
                [
                    'mounted_on',
                    '/cygdrive/d'
                ]
            ],
            [
                'row',
                [
                    'fs',
                    'E:'
                ],
                [
                    'size',
                    '38G'
                ],
                [
                    'used',
                    '9.6G'
                ],
                [
                    'avail',
                    '28G'
                ],
                [
                    'use_percent',
                    '26%'
                ],
                [
                    'mounted_on',
                    '/cygdrive/e'
                ]
            ]
        ]
    ]
Другие вопросы по тегам