AWK如何解析不规则文件
嗨,我需要从非常大的文件日志生成报告。现在我用awk写了一行代码,这已经足够满足我的需要了,现在我被卡住了 我写了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 '{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中阅读关于表的内容,当我能理解时,我会尝试改进这段代码。谢谢您的时间。它可以正常工作,没有任何变化,我可以理解:。谢谢。它可以正常工作,没有任何变化,我可以理解:。非常感谢。