我需要解析具有以下格式化数据的文件并获取 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系统,任何人都知道我应该使用什么命令行工具 我需要什么样的正则表达式来捕获数据 我概述的方式。
任何帮助表示赞赏,
泰德
答案 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>