问题描述
我有一个包含以下内容的文件。它是设备中查询的结果,因此可以预期在数据库中找不到某些输入。以下示例是成功和不成功查询的结果。我的意思是,第二个示例没有将要捕获的所有信息都包含在变量中,因此我想忽略此结果,并使用空值/空值设置变量。
<INTLPO:ISV=PORTAB NTL="6130290095" VEM=NAO;
VECTURA - SS BSA002 2020-09-12 09-32
INTLPO:ISV=PORTAB NTL="6130290095" VEM=NAO;
INTERROGACAO DE NUMERO TELEFONICO Para PORTABILIDADE NUMERICA
TIPO DE ENCAMINHAMENTO POR ASSINANTE
NTL = 6130290095 OPC = S_INF RNP = 551 CSP = 25
EIP = S_INF
CDO = 00961
CNL = 61000 NUF = S_INF TPB = PREST
CPT = NAO CRE = 125 NUE = S_INF
DAT = 2014-04-16 HOR = 10:30:20.798609
TBR = 25
RST MAN RST MAN RST MAN
2% 934 3% 934 4% 934
5% 934 6% 934 7% 934
8% 934 9% 934 9090% 934
0??% 934 90??% 934 0?0% 934
TOTAL DE NUMEROS ASSOCIADOS AO SERVICO: 1
<INTLPO:ISV=PORTAB NTL="6160150178" VEM=NAO;
VECTURA - SS BSA002 2020-09-12 09-32
INTLPO:ISV=PORTAB NTL="6160150178" VEM=NAO;
INTERROGACAO DE NUMERO TELEFONICO Para PORTABILIDADE NUMERICA
ME: NENHUM NUMERO CADASTradO ATENDE AS ESPECIFICACOES
我有以下代码,部分可以。结果还有些混乱(这些行正在重复,甚至具有错误的值)。
awk -F ' ' 'BEGIN { OFS="," }
/^VECTURA/ { equipment = $4; data = $5 }
/^INTLPO/ { numero = $2}
/^\s*NTL/ { ntl = $3 ; opc = $6; rnp = $9; csp = $12}
/^\s*EIP/ { eip = $3}
/^\s*CDO/ { cdo = $3}
/^\s*CNL/ { cnl = $3; nuf = $6; tpb = $9}
/^\s*CPT/ { cpt = $3; cre = $6; nue = $9}
/^\s*DAT/ { dat = $3; hor = $6}
/^\s*TBR/ { tbr = $3}
/^\s*RST/ { man = $2; next}
{ print data,equipment,numero,ntl,opc,rnp,csp,eip,cdo,cnl,nuf,tpb,cpt,cre,nue,dat,hor,tbr,man}' input.tx >> output.txt
结果
2020-09-12,BSA002,6160150536,2020-09-12,6130290095,S_INF,551,25,00961,61000,PREST,NAO,125,2014-04-16,10:30:20.798609,MAN
2020-09-12,6160150178,MAN
请注意,记录6130290095(变量NTL)与“数字”记录(上面示例的最后几行)错误地关联了。
我该如何克服?我尝试了一些AWK条件语句,但也没有成功。 作为输出,我只希望按记录一行,正如输出示例中的某些行可以举例说明的那样。 非常感谢。
解决方法
当您只想更改numero
的值时,请添加一个类似numero ||
的测试。
阅读您的评论后,我更改了解决方案。正如我现在所了解的,您不希望有一条记录将所有块组合在一起的结果,但是您希望每个处理的块有一条结果行。每个新块均以<INTLPO
开头。
此解决方案将使新块开始时的所有值都为空(第一个块不需要此值,但不会造成损害)。
当找到新的块时以及文件的末尾时,都会显示块的结果。
awk 'function newrecord() {
recordnumber++;
data=equipment=numero=ntl=opc=rnp=csp=eip=cdo="";
cnl=nuf=tpb=cpt=cre=nue=dat=hor=tbr=man="";
}
function printrecord() {
print data,equipment,numero,ntl,opc,rnp,csp,eip,cdo,cnl,nuf,tpb,cpt,cre,nue,dat,hor,tbr,man;
}
BEGIN { OFS="," }
/^<INTLPO/ { if (recordnumber) printrecord(); newrecord(); }
/^VECTURA/ { equipment = $4; data = $5 }
/^INTLPO/ { numero = $2}
/^\s*NTL/ { ntl = $3 ; opc = $6; rnp = $9; csp = $12}
/^\s*EIP/ { eip = $3}
/^\s*CDO/ { cdo = $3}
/^\s*CNL/ { cnl = $3; nuf = $6; tpb = $9}
/^\s*CPT/ { cpt = $3; cre = $6; nue = $9}
/^\s*DAT/ { dat = $3; hor = $6}
/^\s*TBR/ { tbr = $3}
/^\s*RST/ { man = $2; next}
END { printrecord(); }
' input.tx
,
在拥有tag = value
对的情况下解决任何问题的最佳方法是,首先填充该映射的数组(下面的tag2val[]
),然后您可以通过其标签(名称)访问所需的任何值)以您喜欢的任何顺序。
$ cat tst.awk
BEGIN {
OFS = ","
numTags = split("\
EQUIPMENT \
DATE \
NUMERO \
NTL \
OPC \
RNP \
CSP \
EIP \
CDO \
CNL \
NUF \
TPB \
CPT \
CRE \
NUE \
DAT \
HOR \
TBR \
MAN \
",tags)
for (tagNr=1; tagNr<=numTags; tagNr++) {
tag = tags[tagNr]
printf "%s%s",tag,(tagNr<numTags ? OFS : ORS)
}
}
/^</ && (NR > 1) {
prt()
delete tag2val
}
$1 == "VECTURA" {
tag2val["EQUIPMENT"] = $4
tag2val["DATE"] = $5
}
/^INTLPO/ {
gsub(/^[^"]+"|"$/,"",$2)
tag2val["NUMERO"] = $2
}
/^([[:space:]]*[^[:space:]]+ = [^[:space:]]+)+$/ {
for (i=1; i<NF; i+=3) {
tag2val[$i] = $(i+2)
}
}
nextLineTag != "" {
tag2val[nextLineTag] = $2
nextLineTag = ""
}
/^[[:space:]]*RST[[:space:]]+MAN/ {
nextLineTag = "MAN"
}
END { prt() }
function prt( tagNr,val) {
for (tagNr=1; tagNr<=numTags; tagNr++) {
tag = tags[tagNr]
val = tag2val[tag]
printf "%s%s",val,(tagNr<numTags ? OFS : ORS)
}
}
。
$ awk -f tst.awk file
EQUIPMENT,DATE,NUMERO,NTL,OPC,RNP,CSP,EIP,CDO,CNL,NUF,TPB,CPT,CRE,NUE,DAT,HOR,TBR,MAN
BSA002,2020-09-12,6130290095,S_INF,551,25,00961,61000,PREST,NAO,125,2014-04-16,10:30:20.798609,934
BSA002,6160150178,