Я хочу прочитать файл и сохранить некоторые переменные с помощью AWK

#regex #shell #awk #readfile #text-processing

#регулярное выражение #оболочка #awk #readfile #обработка текста

Вопрос:

У меня есть файл со следующим содержимым. это результат запроса в оборудовании, поэтому ожидается, что некоторые входные данные не найдены в базе данных. Следующие примеры являются результатом успешных и неуспешных запросов. Я имею в виду, что во втором примере нет всей информации, которую я хочу записать в переменные, поэтому я хочу проигнорировать этот результат и установить переменные с нулевыми / пустыми значениями.

 <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,BSA002,6160150536,,,,,,,,,,,,,,,,
2020-09-12,BSA002,6130290095,,,,,,,,,,,,,,,,
2020-09-12,BSA002,6130290095,,,,,,,,,,,,,,,,
2020-09-12,BSA002,6130290095,,,,,,,,,,,,,,,,
2020-09-12,BSA002,6130290095,,,,,,,,,,,,,,,,
2020-09-12,BSA002,6130290095,6130290095,S_INF,551,25,,,,,,,,,,,,
2020-09-12,BSA002,6130290095,6130290095,S_INF,551,25,S_INF,,,,,,,,,,,
2020-09-12,BSA002,6130290095,6130290095,S_INF,551,25,S_INF,00961,,,,,,,,,,
2020-09-12,BSA002,6130290095,6130290095,S_INF,551,25,S_INF,00961,61000,S_INF,PREST,,,,,,,
2020-09-12,BSA002,6130290095,6130290095,S_INF,551,25,S_INF,00961,61000,S_INF,PREST,NAO,125,S_INF,,,,
2020-09-12,BSA002,6130290095,6130290095,S_INF,551,25,S_INF,00961,61000,S_INF,PREST,NAO,125,S_INF,2014-04-16,10:30:20.798609,,
2020-09-12,BSA002,6130290095,6130290095,S_INF,551,25,S_INF,00961,61000,S_INF,PREST,NAO,125,S_INF,2014-04-16,10:30:20.798609,25,
2020-09-12,BSA002,6130290095,6130290095,S_INF,551,25,S_INF,00961,61000,S_INF,PREST,NAO,125,S_INF,2014-04-16,10:30:20.798609,25,MAN
2020-09-12,BSA002,6130290095,6130290095,S_INF,551,25,S_INF,00961,61000,S_INF,PREST,NAO,125,S_INF,2014-04-16,10:30:20.798609,25,MAN
2020-09-12,BSA002,6130290095,6130290095,S_INF,551,25,S_INF,00961,61000,S_INF,PREST,NAO,125,S_INF,2014-04-16,10:30:20.798609,25,MAN
2020-09-12,BSA002,6130290095,6130290095,S_INF,551,25,S_INF,00961,61000,S_INF,PREST,NAO,125,S_INF,2014-04-16,10:30:20.798609,25,MAN
2020-09-12,BSA002,6130290095,6130290095,S_INF,551,25,S_INF,00961,61000,S_INF,PREST,NAO,125,S_INF,2014-04-16,10:30:20.798609,25,MAN
2020-09-12,BSA002,6130290095,6130290095,S_INF,551,25,S_INF,00961,61000,S_INF,PREST,NAO,125,S_INF,2014-04-16,10:30:20.798609,25,MAN
2020-09-12,BSA002,6130290095,6130290095,S_INF,551,25,S_INF,00961,61000,S_INF,PREST,NAO,125,S_INF,2014-04-16,10:30:20.798609,25,MAN
2020-09-12,BSA002,6130290095,6130290095,S_INF,551,25,S_INF,00961,61000,S_INF,PREST,NAO,125,S_INF,2014-04-16,10:30:20.798609,25,MAN
2020-09-12,BSA002,6130290095,6130290095,S_INF,551,25,S_INF,00961,61000,S_INF,PREST,NAO,125,S_INF,2014-04-16,10:30:20.798609,25,MAN
2020-09-12,BSA002,6130290095,6130290095,S_INF,551,25,S_INF,00961,61000,S_INF,PREST,NAO,125,S_INF,2014-04-16,10:30:20.798609,25,MAN
2020-09-12,BSA002,6130290095,6130290095,S_INF,551,25,S_INF,00961,61000,S_INF,PREST,NAO,125,S_INF,2014-04-16,10:30:20.798609,25,MAN
2020-09-12,BSA002,6130290095,6130290095,S_INF,551,25,S_INF,00961,61000,S_INF,PREST,NAO,125,S_INF,2014-04-16,10:30:20.798609,25,MAN
2020-09-12,BSA002,6160150178,6130290095,S_INF,551,25,S_INF,00961,61000,S_INF,PREST,NAO,125,S_INF,2014-04-16,10:30:20.798609,25,MAN
2020-09-12,BSA002,6160150178,6130290095,S_INF,551,25,S_INF,00961,61000,S_INF,PREST,NAO,125,S_INF,2014-04-16,10:30:20.798609,25,MAN
2020-09-12,BSA002,6160150178,6130290095,S_INF,551,25,S_INF,00961,61000,S_INF,PREST,NAO,125,S_INF,2014-04-16,10:30:20.798609,25,MAN
2020-09-12,BSA002,6160150178,6130290095,S_INF,551,25,S_INF,00961,61000,S_INF,PREST,NAO,125,S_INF,2014-04-16,10:30:20.798609,25,MAN
2020-09-12,BSA002,6160150178,6130290095,S_INF,551,25,S_INF,00961,61000,S_INF,PREST,NAO,125,S_INF,2014-04-16,10:30:20.798609,25,MAN
2020-09-12,BSA002,6160150178,6130290095,S_INF,551,25,S_INF,00961,61000,S_INF,PREST,NAO,125,S_INF,2014-04-16,10:30:20.798609,25,MAN
2020-09-12,BSA002,6160150178,6130290095,S_INF,551,25,S_INF,00961,61000,S_INF,PREST,NAO,125,S_INF,2014-04-16,10:30:20.798609,25,MAN
  

обратите внимание, что запись 6130290095 (переменная NTL) ошибочно связана с записью «number» (последние строки примера выше).

Как я мог бы это преодолеть? Я попробовал некоторый условный оператор AWK, но тоже не увенчался успехом. В качестве вывода я хотел бы получить только одну строку по записи, как это видно из некоторых строк выходного примера. большое спасибо.

Комментарии:

1. Если вы хотите напечатать результат только один раз, используйте END { print ...} .

2. Пожалуйста, укажите ожидаемый результат для вашего образца входного файла. Это файл и как он выглядит? (Или массив bash?)

3. Я не хочу печатать только один раз. Я хочу печатать только один раз для каждой записи . Например: у меня есть список из 50 запросов, и некоторые из них содержат всю необходимую мне информацию, а некоторые нет. На выходе получается список из 50 записей «number», для тех, у кого есть вся информация, я хотел бы напечатать их, разделенных символом coma (как последние в примере, представленном ранее), а для тех, у кого его нет, напечатать как «6130300000, BSA2,,,,,,,,,,,,,,,,,,,,»…..

4. входные данные представляют собой файл, как показано в сценарии (input.txt >> output.txt ).. Еще раз спасибо.

5. Что вы хотите извлечь из ПЕРВЫХ строк MAN?

Ответ №1:

Если вы хотите изменить значение только 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
  

Комментарии:

1. Привет. Спасибо за ответ. Я пробовал это и не сработало. У меня есть файл с сотнями результатов, подобных примерам в вопросе. Часть из них не содержит информации о результатах (потому что эти записи не существуют в базе данных оборудования). Но я хочу записать вывод со всеми записями. Одна строка на входную запись со всей доступной информацией. Когда в блоке информации нет всей информации, я хотел бы распечатать их с минимальной информацией, которая у них есть (например, 2020-09-12, BSA2,6130300020,,,,,,,,,,,,)…

2. большое вам спасибо, вы поняли это. ваше решение элегантное, но простое, оно сработало точно, нет слов, чтобы поблагодарить вас.

Ответ №2:

Лучший способ решить любую проблему, в которой у вас есть 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)
    }
}
/^</ amp;amp; (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, tag, 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,6130290095,S_INF,551,25,S_INF,00961,61000,S_INF,PREST,NAO,125,S_INF,2014-04-16,10:30:20.798609,25,934
BSA002,2020-09-12,6160150178,,,,,,,,,,,,,,,,