AWK:处理多个定界符标准的优雅方法

时间:2018-06-24 09:57:47

标签: regex awk

我正在用awk处理日志文件。一些行是这样的:

  

[TIME] [TYPE]条目A:a条目B:b条目C:{c1:val1,c2:val2}

所有主字段都类似于name:valuename:{subentries}(子条目在冒号后有空格)。 到目前为止,我可以使用空格分隔符来处理普通条目,也可以使用正则表达式来匹配{}中的内容,并在其中包含子条目的情况下提取数据(例如/([^\s]*:\s[^\s]*),/)。但是并非所有{}块都包含子条目,出于某种原因,我认为最好将主条目和子条目的处理分开。

是否可以一次提取所有主字段?

编辑:

我希望期望输出的主要条目如下:

  

entryA entryB entryC

此外,我想知道是否可以维护一个数组来记录条目是否有其自己的子条目。

1 个答案:

答案 0 :(得分:1)

编辑: 或使用sed,以下内容可能对您有帮助,在Input_file上进行测试时,首次尝试提及了此帖子。

sed 's#entry[A-Z]:{.*}##g;s#\[TIME\] ##;s#\[TYPE\] ##'  Input_file

由于您没有在帖子中提到预期的输出,因此根据您提到的摘要,只编写了代码,该代码将删除行中带有{c1: val1, c2: val2}的所有值并打印所有其他值。

让我们说以下是Input_file。

cat Input_file
[TIME] [TYPE] entryA:a entryB:b entryC:{c1: val1, c2: val2} entryA:a entryB:b

然后是此代码:

awk '
{
   while($0) {
      match($0,/entry[a-zA-Z]+:{[^}]*\}/)
      val=substr($0,1,RSTART-1)
      gsub(/\[TYPE\] |\[TIME\] /,"",val)
      if(RSTART>1) {
         printf("%s",val)
      }
      if(RSTART && RLENGTH) {
         $0=substr($0,RSTART+RLENGTH+1)
      }
      else {
         printf("%s\n",substr($0,pre_start+pre_end+1))
         next
      }
      prev_start=RSTART
      prev_end=RLENGTH
   }
}
'  Input_file

输出如下。

entryA:a entryB:b entryA:a entryB:b