AWK如何解析不规则文件

AWK如何解析不规则文件,awk,Awk,嗨,我需要从非常大的文件日志生成报告。现在我用awk写了一行代码,这已经足够满足我的需要了,现在我被卡住了 我写了awk代码: awk '{if ($1 == "GR" && $4 == "NGR") {c = $3; n = $6} else if ($1 == "NAME") {m = $3} else if ($1 == "PCM-TSL" || $1 == "TERMID") {s = "1"} else if (s == "1" && $1 ~ "-")

嗨,我需要从非常大的文件日志生成报告。现在我用awk写了一行代码,这已经足够满足我的需要了,现在我被卡住了

我写了awk代码:

awk '{if ($1 == "GR" && $4 == "NGR") {c = $3; n = $6} else if ($1 == "NAME") {m = $3} else if ($1 == "PCM-TSL" || $1 == "TERMID") {s = "1"} else if (s == "1" && $1 ~ "-") {split ($1,pcm,"-")} else if (s == "1" && p == pcm[1]) {next}  else if (c != "" && n != "" ) {p = pcm[1]; print c " " n " "m " " p  }}' DATA_FILE
或者说分手了:

awk '
        {
        if ($1=="GR" && $4=="NGR") {
            c=$3
            n=$6} 
        else if ($1=="NAME") {
            m=$3} 
        else if ($1=="PCM-TSL" || $1=="TERMID") {
            s="1"} 
        else if (s=="1" && $1~"-") {
            split ($1,pcm,"-")} 
        else if (s=="1" && p==pcm[1]) {
            next}  
        else if (c!="" && n!="" ) {
            p = pcm[1]
            print c,n,m,p}
        }' DATA_FILE
它以正确的格式显示数据,但对于一个GR&NGR&NAME仅显示一条记录

我需要展示:

GR   NGR   NAME PCM
200  D200E AAA1 4
200  D200E AAA1 8
200  D200E AAA1 ...
220  DA30E BBA1 1
220  DA30E BBA1 2
...
下面是日志示例:

 GROUP(S)
some unused data....
GR      : 200             NGR     : D200E           

NAME : AAA1
some unused data....    
DR1A  : -      DR2A  : -      ART1A : -      ART2A : -      ACT : NO 
DR1B  : -      DR2B  : -      ART1B : -      ART2B : -      ACT : NO  
DR1C  : -      DR2C  : -      ART1C : -      ART2C : -      ACT : NO 

CIRCUIT(S)

PCM-TSL              ORD      CTRL     HGR      STATE    LSI        

4-0                  1        X        1-1      ACT    -          
4-1                  2        X        1-2      ACT    -          
4-2                  3        X        1-3      ACT    -          
4-3                  4        X        1-4      ACT    -          
4-4                  5        X        1-5      ACT    -          
4-5                  6        X        1-6      ACT    -          
4-6                  7        X        1-7      ACT    -          
4-7                  8        X        1-8      ACT    -          
4-8                  9        X        1-9      ACT    -          
4-9                  10       X        1-10     ACT    -          
4-10                 11       X        1-11     ACT    -          
8-5                  6        X        1-6      ACT    -          
8-6                  7        X        1-7      ACT    -          
8-7                  8        X        1-8      ACT    -          
8-8                  9        X        1-9      ACT    -          
8-9                  10       X        1-10     ACT    -          
8-10                 11       X        1-11     ACT    -


 GROUP(S)

GR      : 220             NGR     : DA30E           

NAME : BBA1

DR1A  : -      DR2A  : -      ART1A : -      ART2A : -      ACT : NO 
DR1B  : -      DR2B  : -      ART1B : -      ART2B : -      ACT : NO  
DR1C  : -      DR2C  : -      ART1C : -      ART2C : -      ACT : NO 
some unused data....
CIRCUIT(S)

PCM-TSL              ORD      CTRL     HGR      STATE    LSI        

1-0                  1        X        1-1      ACT    -          
1-1                  2        X        1-2      ACT    -          
1-2                  3        X        1-3      ACT    -          
1-3                  4        X        1-4      ACT    -          
1-4                  5        X        1-5      ACT    -          
1-5                  6        X        1-6      ACT    -          
1-6                  7        X        1-7      ACT    -          
1-7                  8        X        1-8      ACT    -          
1-8                  9        X        1-9      ACT    -          
1-9                  10       X        1-10     ACT    -          
1-10                 11       X        1-11     ACT    -          
2-5                  6        X        1-6      ACT    -          
2-6                  7        X        1-7      ACT    -          
2-7                  8        X        1-8      ACT    -          
2-8                  9        X        1-9      ACT    -          
2-9                  10       X        1-10     ACT    -          
2-10                 11       X        1-11     ACT    -


more simmilar blocks

关于Tom

这样做的一般方法是根据输入构建一个数组,并在每次到达下一条记录时打印它。像这样未经测试但应该很接近:

awk '
function prtRec(    pcm,numPcm) {
    print "GR", "NGR", "NAME", "PCM"
    numPcm = split(rec["PCM"],pcm) - 1
    for (i=1; i<=numPcm; i++) {
        print rec["GR"], rec["NGR"], rec["NAME"], pcm[i]
    }
    split("",rec)     # or delete(rec) in gawk
}

/:/ {
    for (i=1; i<=NF; i+=3) {
        rec[$i] = $(i+2)
    }
}

/^PCM/ {
    inPcm = 1
}

inPcm && NF {
    split($1,pcmTsl,/-/)
    rec["PCM"] = rec["PCM"] pcmTsl[1] " "
}

/^[[:space:]]*]GROUP\(s\)[[:space:]]*$/ { inPcm=0; prtRec() }

END { prtRec() }

' file

一般的方法是根据输入构建一个数组,并在每次到达下一条记录时打印它。像这样未经测试但应该很接近:

awk '
function prtRec(    pcm,numPcm) {
    print "GR", "NGR", "NAME", "PCM"
    numPcm = split(rec["PCM"],pcm) - 1
    for (i=1; i<=numPcm; i++) {
        print rec["GR"], rec["NGR"], rec["NAME"], pcm[i]
    }
    split("",rec)     # or delete(rec) in gawk
}

/:/ {
    for (i=1; i<=NF; i+=3) {
        rec[$i] = $(i+2)
    }
}

/^PCM/ {
    inPcm = 1
}

inPcm && NF {
    split($1,pcmTsl,/-/)
    rec["PCM"] = rec["PCM"] pcmTsl[1] " "
}

/^[[:space:]]*]GROUP\(s\)[[:space:]]*$/ { inPcm=0; prtRec() }

END { prtRec() }

' file
你可以试试

awk -f ext.awk DATA_FILE
ext.awk在哪里

你可以试试

awk -f ext.awk DATA_FILE
ext.awk在哪里

问题 以下是我如何理解您的问题:

如果看到带有GR和NGR的行,请保存这些值 名字也是一样 PCM-TSL或TERMID标记表格的标题 一旦找到一个表,您希望输出PCM值$1破折号之前的数字,但不希望数字重复。 解决方案 根据我对问题的理解,以下是我的解决方案,文件summary.awk:

跑步 我将脚本保存为summary.awk,将数据文件保存为data_文件:

awk -f summary.awk DATA_FILE 
以下是输出:

GR  NGR    NAME   PCM
200 D200E  AAA1   4
200 D200E  AAA1   8
220 DA30E  BBA1   1
220 DA30E  BBA1   2
讨论 我正试图以尽可能清晰的方式写作。如果你需要解释,请告诉我。 我注意到包含组的行似乎是表的结尾,所以我使用了它。 我发现棘手的部分是识别表中的一行,表达式$1~/[0-9][0-9-]*/表示第一列必须以数字开头,然后是数字或破折号。 当脚本变得有点复杂时,即跨越几行时,最好将其保存到文件中,而不是每次需要进行更改时都必须编辑命令行。 问题 以下是我如何理解您的问题:

如果看到带有GR和NGR的行,请保存这些值 名字也是一样 PCM-TSL或TERMID标记表格的标题 一旦找到一个表,您希望输出PCM值$1破折号之前的数字,但不希望数字重复。 解决方案 根据我对问题的理解,以下是我的解决方案,文件summary.awk:

跑步 我将脚本保存为summary.awk,将数据文件保存为data_文件:

awk -f summary.awk DATA_FILE 
以下是输出:

GR  NGR    NAME   PCM
200 D200E  AAA1   4
200 D200E  AAA1   8
220 DA30E  BBA1   1
220 DA30E  BBA1   2
讨论 我正试图以尽可能清晰的方式写作。如果你需要解释,请告诉我。 我注意到包含组的行似乎是表的结尾,所以我使用了它。 我发现棘手的部分是识别表中的一行,表达式$1~/[0-9][0-9-]*/表示第一列必须以数字开头,然后是数字或破折号。 当脚本变得有点复杂时,即跨越几行时,最好将其保存到文件中,而不是每次需要进行更改时都必须编辑命令行。
这段代码几乎没问题,有时重复我必须在awk中阅读的关于表的相同记录,当我理解它时,我会尝试改进这段代码。谢谢你的时间。这段代码几乎没问题。有时我会重复同样的记录,我必须在awk中阅读关于表的内容,当我能理解时,我会尝试改进这段代码。谢谢您的时间。它可以正常工作,没有任何变化,我可以理解:。谢谢。它可以正常工作,没有任何变化,我可以理解:。非常感谢。