我想读取文件并使用AWK存储一些变量

问题描述

我有一个包含以下内容文件。它是设备中查询的结果,因此可以预期在数据库中找不到某些输入。以下示例是成功和不成功查询的结果。我的意思是,第二个示例没有将要捕获的所有信息都包含在变量中,因此我想忽略此结果,并使用空值/空值设置变量。

<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,