анализировать текстовый файл с элементами, разделенными скобками {} - PullRequest
0 голосов
/ 17 февраля 2011

Есть ли способ проанализировать текстовый файл, который включает элементы, разделенные {} s

Вот пример из файла:

virtual vs_devtnet_80 {
   snat automap
   pool pool_devtnet_80
   destination 167.69.107.41:http
   ip protocol tcp
   profiles {
      profile_http_health {}
      tcp-lan-optimized {}
   }
}
virtual vs_devdpp_4430 {
   snat automap
   pool pool_devdpp_5430
   destination 167.69.107.31:https
   ip protocol tcp
   persist devdpp
   profiles tcp-lan-optimized {}
}
virtual vs_devwww30_80 {
   snat automap
   pool pool_devwww30_80
   destination 167.69.107.46:http
   ip protocol tcp
   profiles {
      profile_http_health {}
      tcp-lan-optimized {}
   }
}

Как видите,элементы разделены, но с {}

Любая помощь будет с благодарностью.Я пытался использовать grep, но он возвращает только одну строку ...

Я хотел бы иметь возможность выполнять поиск по самому верхнему элементу, например, по запросу searh.sh virtual vs_devtnet_80, и вернуть его целиком... кроме того, возможно, можно будет найти как верхний уровень, так и один из его подуровней, например, search.sh виртуальный пул vs_devtnet_80, который будет возвращать pool_devtnet_80

Ответы [ 5 ]

0 голосов
/ 21 февраля 2011

В итоге мне пришлось создать рекурсивную функцию, которая сначала использовала strpos для поиска переменной поиска во всем файле конфигурации.Затем с помощью рекурсивной функции pop'd on и pop'd off скобки возвращаем все тело искомой переменной.

0 голосов
/ 17 февраля 2011

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

#!/usr/bin/env tclsh

# create a safe slave interpreter
set slave [interp create -safe]

# set up the slave to parse the input file
$slave eval {
    proc virtual {subkey body} {
        eval $body
    }
    proc unknown {cmd args} {
        upvar 1 subkey subkey  ;# access the 'subkey' variable from the 'virtual' proc
        if {[llength $args] == 1} {set args [lindex $args 0]}
        dict set ::data $subkey $cmd $args
    }
    set data [dict create]
}
$slave expose source

# now do the parsing in the slave
$slave eval source [lindex $argv 0]

# fetch the data structure
set data [$slave eval set data]

# and do stuff with it.
dict for {subkey subdict} $data {
    puts "$subkey destination = [dict get $subdict destination]"
}

А потом parser.tcl input_file выводит

vs_devaetnet_80 destination = 167.69.107.41:http
vs_devdpp_4430 destination = 167.69.107.31:https
vs_devwww30_80 destination = 167.69.107.46:http
0 голосов
/ 17 февраля 2011

Посмотрите на JSON pasers, они написаны на всех языках, синтаксис выглядит достаточно схожим, чтобы дать вам некоторые идеи о том, как справиться с этим.

По сути, вам нужно иметь рекурсивную функцию, которая вызывает себя каждый раз, когда встречает «{», и возвращает содержимое всякий раз, когда встречает «}».Я написал статью о парсеподобном парсере, который на самом деле делает именно это.Проверьте это здесь для вдохновения: http://www.codeproject.com/KB/linq/TinyLisp.aspx

Rgds Gert-Jan

0 голосов
/ 17 февраля 2011

Это должно дать вам 2-й «блоб», например:

sed -n '/virtual vs_devdpp_4430.*/,/^}$/p' filename.txt

и пройдите через grep -oP '(?<=pool ).*', чтобы получить то, что следует pool в этом BLOB-объекте.

0 голосов
/ 17 февраля 2011

Что-то вроде:

cat .tmp | sed '/.*{/ ! { s/.*//g}'

это не решит проблему полностью, но я думаю, что она делает нечто похожее на то, что вы хотите

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...