我必须解析一个文件,一种配置文件,它采用非常简单的语法:有两种多行块和内联标记。
类型 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 个字符)的行,我们都会根据所在的块打印出内容。