awk正则表达式嵌套大括号

时间:2016-09-27 20:45:57

标签: regex awk

我有这样的结构:

label1 {
   label1_1 {

      item1_1_1: "value1_1_1";
      label1_1_2:{ item1_1_2_1: "value1_1_2_1";};

      item1_1_3: "value1_1_3";
   };

   label1_2 {...};
   ...
};

label2 {
   item2_1: "value2_1";
   label2_1:{
      item2_1_1: "value2_1_1";
      ...
   };
};

该部分可以是一行或多行,并且可以显示空行。我正在尝试使用awk来获取具有给定标签名称的任何部分,

section=$(awk -v RS='' -v ORS='\n\n' "/($2)\s(\{([^{}]|(?R)|\n)*\})/" $1)

其中$ 1是文件名,$ 2是标签名称。如果在该部分中没有空行,例如“label2”,则会有效,但是由其他人发现。

我应该使用正确的正则表达式是什么?

1 个答案:

答案 0 :(得分:3)

这是一种做你想要的方法,假设{}都不能出现在带引号的字符串中,并使用GNU awk 4. *进行几个扩展:

$ cat tst.awk
BEGIN { RS="^$" }
{
    tmp = $0
    while ( match(tmp,/(\<([[:alnum:]_]+):?\s*{[^{}]+};)/,a) ) {
        start[a[2]] = RSTART
        lgth[a[2]]  = RLENGTH
        tmp = substr(tmp,1,RSTART-1) sprintf("%*s",length(a[1]),"") substr(tmp,RSTART+RLENGTH)
    }
}
label in start { print substr($0,start[label],lgth[label]) }

$ awk -v label='label2' -f tst.awk file
label2 {
   item2_1: "value2_1";
   label2_1:{
      item2_1_1: "value2_1_1";
      ...
   };
};

$ awk -v label='label1_1' -f tst.awk file
label1_1 {

      item1_1_1: "value1_1_1";
      label1_1_2:{ item1_1_2_1: "value1_1_2_1";};

      item1_1_3: "value1_1_3";
   };

$ awk -v label='label1_1_2' -f tst.awk file
label1_1_2:{ item1_1_2_1: "value1_1_2_1";};

您可以将awk称为awk -f scriptfile inputfileawk 'script' inputfile,以便使用上面的awk脚本内联而不是存储在文件中只是:

awk '
BEGIN { RS="^$" }
{
    tmp = $0
    while ( match(tmp,/(\<([[:alnum:]_]+):?\s*{[^{}]+};)/,a) ) {
        start[a[2]] = RSTART
        lgth[a[2]]  = RLENGTH
        tmp = substr(tmp,1,RSTART-1) sprintf("%*s",length(a[1]),"") substr(tmp,RSTART+RLENGTH)
    }
}
label in start { print substr($0,start[label],lgth[label]) }
' file