2016-04-21 2 views
0

Я пытаюсь написать скрипт, который может разобрать следующий вывод -Tcl разбор для вывода команды выходов, не давая никакого вывода

dev1# show stats all 

20:01:02-180 (stats) ID=1a2b3c 
Work Stats   -- Now -- -------- Overall -------- 
       T1 T2 Total  T5  T6 Total 
container  3  3 0   3  3  3 
operatioms   3  3 0   3  3  3 
docker   3  3 0   3  3  3 
tcl   3  3 0   3  3  3 
app   3  3 0   3  3  3 
external   1  4 0 
intra   2  6 0 
incoming locks   8  6 0 
outgoing locks   4  3 0 
race-condition times 10  20  23 
threads/usage   45  56  70 

Power  2.3   10 
Consumption 20.3%  29% 

----------------------------------------------------------------------- 
Separate Command 
----------------------------------------------------------------------- 



dev1# show usage 
    20:01:08-100 
    OS: 48270 % 
    Core: 4524 % 
    User: 90 % 

К сожалению, устройство вывод не отформатирован хорошо.

При просмотре TCL блогах, я нашел один блог, который имел следующий код -

set input [dev1 run "show stats"] 
    array unset output 
    array set output {} 

    foreach line [split $input "\n"] { 
     if {[regexp {^([^:]+?)\s*:\s*(\S+)\s*(\S+)?$} $line ]} { 
      set key [string tolower $key 0 0] 
      set output($key) $value 
      if {[string length $units]} { 
       set output(${key}Unit) $units 

      } 
     } 
    } 


    foreach {key value} [array get output] { 
     puts [list $key $value] 

    } 

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

Ожидаемый выход

stats { 

    {time 20:01:02-180} 
    {id 1a2b3c} 
    {cmd stats} 
    {Now 
     {T1 {container 3} {operatioms 3} {docker 3} {tcl 3} {app 3} {extrenal 3} {intra 2} {incoming_locks 8} {outgoing_locks 4} {race-condition_times 10} {threads/usage 45}} 
     {T2 {container 3} {operatioms 3} {docker 3} {tcl 3} {app 3} {extrenal 4} {intra 6} {incoming_locks 6} {outgoing_locks 3} {race-condition_times 20} {threads/usage 56}} 
     {Total {container 3} {operatioms 3} {docker 3} {tcl 3} {app 3} {extrenal 4} {intra 6} {incoming_locks 0} {outgoing_locks 0} {race-condition_times 23} {threads/usage 70}} 
    } 
    {Overall 
     {T5 {container 3} {operatioms 3} {docker 3} {tcl 3} {app 3} } 
     {T6 {container 3} {operatioms 3} {docker 3} {tcl 3} {app 3} } 
     {Total {container 3} {operatioms 3} {docker 3} {tcl 3} {app 3} } 
    } 
    {Power {current 2.3} {total 10}} 
    {Consumptiomn {current 20.3%} {total 29%}} 

    } 


    ----------------------------------------------------------------------- 
    ----------------------------------------------------------------------- 


    usage { 

    {time 20:01:08-100} 
    {OS 48270%} 
    {Core 4524%} 
    {User 90%} 

    } 

Благодаря

+0

Добро пожаловать в StackOverflow! Чтобы лучше ответить на ваш вопрос, отредактируйте свой вопрос и укажите, что вы не можете получить. Является ли код запущенным, он анализирует некоторые, но не весь ваш вывод, неправильно ли он обрабатывается и т. Д. – buczek

+0

Спасибо @buczek за ваши комментарии. Я обновил вопрос. –

+0

Вы должны заглянуть в свое регулярное выражение, которое не анализирует все строки на входе. Добавьте регулярное выражение для похожих данных и возьмите необходимые значения. – Ashish

ответ

0

Теперь это причудливо формат вывода.

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

Вот две команды, которые анализируют выход из stats/usage команд и данных урожая в ДИКТ структур:

proc parseStats txt { 
    set data {} 
    set keys1 {{Now T1} {Now T2} {Now Total} {Overall T5} {Overall T6} {Overall Total}} 
    set keys2 {{Now T1} {Now T2} {Now Total}} 
    foreach line [split [string trim $txt] \n] { 
     switch -regexp -matchvar m $line { 
      {^\s*(container)\M\s+(.*)} - 
      {^\s*(operations)\M\s+(.*)} - 
      {^\s*(docker)\M\s+(.*)} - 
      {^\s*(tcl)\M\s+(.*)} - 
      {^\s*(app)\M\s+(.*)} { 
       lassign $m -> keystring values 
       foreach key $keys1 val $values { 
        dict set data stats {*}$key $keystring $val 
       } 
      } 
      {^\s*(external)\M\s+(.*)} - 
      {^\s*(intra)\M\s+(.*)} - 
      {^\s*(incoming locks)\M\s+(.*)} - 
      {^\s*(outgoing locks)\M\s+(.*)} - 
      {^\s*(race-condition times)\M\s+(.*)} - 
      {^\s*(threads/usage)\M\s+(.*)} { 
       lassign $m -> keystring values 
       set keystring [string map {{ } _} $keystring] 
       foreach key $keys2 val $values { 
        dict set data stats {*}$key $keystring $val 
       } 
      } 
      {^\s*(Power)\M\s+(.*)} - 
      {^\s*(Consumption)\M\s+(.*)} { 
       lassign $m -> keystring values 
       foreach lbl {current total} val $values { 
        dict set data stats $keystring $lbl $val 
       } 
      } 
      ^\\d { 
       dict set data stats time [lindex $line 0] 
       dict set data stats cmd [string trim [lindex $line 1]()] 
       dict set data stats id [lindex [split [lindex $line 2] =] 1] 
      } 
     } 
    } 
    return $data 
} 

proc parseUsage txt { 
    set data {} 
    foreach line [split [string trim $txt] \n] { 
     switch -regexp -matchvar m $line { 
      {^\s*(OS)\M:\s+(.*)} - 
      {^\s*(Core)\M:\s+(.*)} - 
      {^\s*(User)\M:\s+(.*)} { 
       lassign $m -> keystring values 
       dict set data usage $keystring [join $values {}] 
      } 
      ^\\d { 
       dict set data usage time $line 
      } 
     } 
    } 
    return $data 
} 

Если предположить, что выход из команды stats находится в переменной statsText, а выходной сигнал от Команда usage находится в переменной usageText, вы можете построить эти структуры словаря (обратите внимание, что фактический вывод заполнен белым цветом: я добавил новые строки и отступы для удобочитаемости).

% set stats [parseStats $statsText] 
% set stats 
stats { 
    time 20:01:02-180 
    cmd stats 
    id 1a2b3c 
    Now { 
     T1 {container 3 docker 3 tcl 3 app 3 external 1 intra 2 incoming_locks 8 outgoing_locks 4 race-condition_times 10 threads/usage 45} 
     T2 {container 3 docker 3 tcl 3 app 3 external 4 intra 6 incoming_locks 6 outgoing_locks 3 race-condition_times 20 threads/usage 56} 
     Total {container 0 docker 0 tcl 0 app 0 external 0 intra 0 incoming_locks 0 outgoing_locks 0 race-condition_times 23 threads/usage 70} 
    } 
    Overall { 
     T5 {container 3 docker 3 tcl 3 app 3} 
     T6 {container 3 docker 3 tcl 3 app 3} 
     Total {container 3 docker 3 tcl 3 app 3} 
    } 
    Power {current 2.3 total 10} 
    Consumption {current 20.3% total 29%} 
} 

% set usage [parseUsage $usageText] 
% set usage 
usage { 
    time 20:01:08-100 
    OS 48270% 
    Core 4524% 
    User 90% 
} 

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

Если вы должны держать в формат вывода, как показано на рисунке, следующая команда преобразует dict структуру в строку, которая функционально эквивалентны, если не Пробельные эквивалент:

proc prettyPrintDict dict { 
    dict for {k v} $dict { 
     if {[llength $v] == 1} { 
      append res "{$k $v}\n" 
     } else { 
      append r [prettyPrintDict $v] 
      append res "$k {\n$r}\n" 
      set r {} 
     } 
    } 
    return $res 
} 

% puts [prettyPrintDict [parseStats $statsText]] 
% puts [prettyPrintDict [parseUsage $usageText]] 

Обратите внимание, что она опирается на все значения - слова без пробелов.

Документация: append, dict, foreach, if, lassign, proc, puts, return, set, split, string, switch

+0

Спасибо @Peter .... Один из случаев работал на меня. Для другого набора у меня разные ключи и некоторые пробелы. Есть ли способ удалить белые пробелы только из части ввода? –

+0

@CentosNewbie: обязательно. Селектора 'switch' - это просто регулярные выражения, а группировка (круглые скобки) указывает, что нужно извлечь, используя' lindex $ m 1'. Если вы обнаружите, что это трудно сделать самостоятельно, обновите свой вопрос с помощью этой новой информации, и я посмотрю, что я могу сделать. –

+0

Я обновил вопрос @Peter. –

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