使用 shell 脚本解析非常简单的标记语法

使用 shell 脚本解析非常简单的标记语法

我必须解析一个文件,一种配置文件,它采用非常简单的语法:有两种多行块和内联标记。

类型 1 的块由开放标签和一个结束标签加上块的名称,例如

START_BLOCK_1 name
   < content >
END_BLOCK_1

类型1的块仅包含类型2的块,它们基本上用于打开或关闭该配置文件的块。

类型 2 的块由新行开头的标记(加上名称)标记,并且有非结束标记,当新块开始或文件结束时隐式结束,允许块本身包含空行。

START_BLOCK_2 name_1
    < content >
    < content >
    < content >

START_BLOCK_2 name_2

    < content >

    < content >
    < content >

START_BLOCK_2 name_3
    < content >
    < content >

最后一种标记只是一个内联标记,一个出现在行开头的特殊单词,我只是为了获取该标记标记的值是什么

START_BLOCK_2 name_1

    tag_1 red

    tag_2 Jon

START_BLOCK_2 name_2
    tag_1 blue
    tag_2 Phil

最后一个很好的例子可能是

START_BLOCK_2 name_1
    < content >

START_BLOCK_2 name_2

    < content >

START_BLOCK_1 name_1
    START_BLOCK_2 name_3
        < content >

    START_BLOCK_2 name_4

        < content >

END_BLOCK_1

START_BLOCK_2 name_5
    < content >

考虑到类型 2 块的名称,我需要知道与每个标记关联的值(如果它们包含已设置的标记)以及它们是否是类型 1 块的一部分,在这种情况下,类型 1 块的名称属性包含他们 。

结果可以存储在文件中或打印出来,只要我可以解析它,我就可以稍后以格式化的方式重新读取输出。

解析这个文件相对简单,但我从来没有只用 GNU/linux shell 做过这样的事情,我想知道这是否可能以及为此制作的工具的名称。

编辑

输入

START_BLOCK_2 opt1
color red

START_BLOCK_1 opt2
    START_BLOCK_2 opt3
        name Jon

    START_BLOCK_2 opt4

        color blu

END_BLOCK_1

预期产出

opt1 red

opt3 opt2
opt3 Jon

opt4 opt2
opt4 blu

答案1

这是一个awk解决方案,假设您不希望示例输出中出现空行。

awk '/START_BLOCK_1/ { block1=$2; next; } \
/END_BLOCK_1/ {block1=""; next; } \
/START_BLOCK_2/ { block2=$2; next; } \
/./ { if(block1) {print block2 " " block1} if(block2) { print block2 " " $2}
}' inp

它的工作原理是匹配每一行的开始或结束块。如果我们位于 BLOCK_1“中”,我们将在变量中设置名称block1。如果我们“在”BLOCK_2 中,我们将在变量中设置该名称block2。任何未定义块且不为空(至少匹配 1 个字符)的行,我们都会根据所在的块打印出内容。

相关内容