解析自定义纯文本文件

时间:2011-11-09 21:42:39

标签: bash unix

我需要解析具有以下格式化数据的文件并获取 OTHER节点的DIRNAME。

    CLASS=
     (SOURCE=
        (TYPE=FILE)
        (DEFAULT=
           (DIRNAME=${HOME}/information/logs)
        )
      )


    OTHER=
     (SOURCE=
        (TYPE=FILE)
        (DEFAULT=
           (DIRNAME=${HOME}/site/location)
        )
      )

    STUDENT=
     (SOURCE=
        (TYPE=FILE)
        (DEFAULT=
           (DIRNAME=/opt/students)
        )
      )

我必须捕获OTHER =字段中包含的所有内容,例如 所以:

    OTHER= <whitespace> ( <to capture> ) 

然后我必须捕获DIRNAME中的所有内容 OTHER =字段,如下:

    (DIRNAME=<to capture>)

我想在一个可以在大多数情况下运行的强大脚本中执行此操作 unix系统,任何人都知道我应该使用什么命令行工具 我需要什么样的正则表达式来捕获数据 我概述的方式。

任何帮助表示赞赏,

泰德

3 个答案:

答案 0 :(得分:2)

见下面的测试:

kent$  cat t
    CLASS=
     (SOURCE=
        (TYPE=FILE)
        (DEFAULT=
           (DIRNAME=${HOME}/information/logs)
        )
      )


    OTHER=
     (SOURCE=
        (TYPE=FILE)
        (DEFAULT=
           (DIRNAME=${HOME}/site/location)
        )
      )

    STUDENT=
     (SOURCE=
        (TYPE=FILE)
        (DEFAULT=
           (DIRNAME=/opt/students)
        )
      )

kent$  awk -F= '$1~/OTHER/{i++;print $2} $1~/DIRNAME/ && i{i=0;gsub(/\)$/,"",$2); print $2}' t

${HOME}/site/location

请注意输出行$ {HOME} / site / location上方有一个空行, 它是OTHER=

之后的空白

答案 1 :(得分:1)

这可能对您有用:

sed -ne '/OTHER/,/DIRNAME/{s/^[^D]*DIRNAME=\(.*\))/\1/p}' input_file
${HOME}/site/location

答案 2 :(得分:0)

您的数据看起来很容易转换为XML。从那里,您可以轻松使用标准XML工具(如XSLT)来准确指定要提取的内容。

对于这个小样本,XML方法可能有点过分,如果你需要处理,例如,转义括号,或需要转义的东西,以便形成格式良好的XML,也许这不值得努力。但如果你想要强大和便携,我会说这是要走的路。

对于它的价值,你的数据看起来像S表达式;也许对于S表达式有xsltproc之类的东西?

这是一个简短的Perl双线程,它似乎可以将您的测试数据转换为某种伪XML。我没有尝试处理根节点;再问一下你是否需要更多的帮助。

$ perl -pe 's{\(([^\s=]+)=|\)}{ if (defined $1) { push @tags, $1; "<$1>" } 
> else { sprintf("</%s>", pop @tags) } }ge' /tmp/data 
CLASS=
 <SOURCE>
    <TYPE>FILE</TYPE>
    <DEFAULT>
       <DIRNAME>${HOME}/information/logs</DIRNAME>
    </DEFAULT>
  </SOURCE>


OTHER=
 <SOURCE>
    <TYPE>FILE</TYPE>
    <DEFAULT>
       <DIRNAME>${HOME}/site/location</DIRNAME>
    </DEFAULT>
  </SOURCE>

STUDENT=
 <SOURCE>
    <TYPE>FILE</TYPE>
    <DEFAULT>
       <DIRNAME>/opt/students</DIRNAME>
    </DEFAULT>
  </SOURCE>