【问题标题】:parse thru txt file with elements separated by {} brakets解析文本文件,其中元素由 {} 括号分隔
【发布时间】:2011-02-17 16:16:18
【问题描述】:

有没有办法通过包含由 {}s 分隔的元素的 txt 文件进行解析

这是文件中的一个示例:

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,并让它返回整个 blob..此外,也许能够搜索顶层及其子层之一层,例如 search.sh 虚拟 vs_devtnet_80 池,它将返回 pool_devtnet_80

【问题讨论】:

  • 你希望解析后的结果是什么?即,您希望如何存储/返回数据?
  • search.sh 是执行解析的组成脚本
  • 当提供顶级元素 virtual vs_devaetnet_80 时,它可以返回单个字符串或子元素数组...即池、destinatino、ip 等

标签: linux parsing shell grep


【解决方案1】:

类似:

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

这不会完全解决它,但我认为它的作用类似于你想要的

【讨论】:

    【解决方案2】:

    看看 JSON 解析器,它们是用各种语言编写的,语法看起来很相似,可以为您提供一些关于如何解决这个问题的想法。

    基本上你需要做的是有一个递归函数,它在遇到'{'时调用自己,并在遇到'}'时返回内容。 我写了一篇关于类似 lisp 的解析器的文章,它实际上就是这样做的。在这里查看灵感:http://www.codeproject.com/KB/linq/TinyLisp.aspx

    Rgds Gert-Jan

    【讨论】:

      【解决方案3】:

      这是 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
      

      【讨论】:

        【解决方案4】:

        这应该给你第二个'blob',例如:

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

        并通过grep -oP '(?<=pool ).*' 获取该blob 中pool 后面的内容。

        【讨论】:

          【解决方案5】:

          我最终不得不创建一个递归函数,它首先使用 strpos 在整个配置文件中查找搜索变量。然后使用递归函数 pop'd on 和 pop'd off 括号返回搜索到的变量的整个主体。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2013-04-19
            • 1970-01-01
            • 2016-05-25
            • 1970-01-01
            • 1970-01-01
            • 2011-01-20
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多