Awk печать конкретных переменных и исходных данных вместе между шаблоном - PullRequest
0 голосов
/ 25 сентября 2018

исходные данные и требуемый вывод

Здравствуйте,

Я хочу получить конкретные значения переменных между шаблонами и печатью ( REF_ID значение, C_ID значение и Дата-время перед ним.

Вы можете увидеть Исходные данные и желаемый результат ниже:

ввод:

[2018 13:50] ALI
REF_ID X 
A 3 
C_ID Y 
B 4 
[2018 14:00] ALI
C 3 
REF_ID Z 
D 1 
E 4 
C_ID T 

необходим вывод:

[2018 13:50] X Y [2018 13:50] ALI
[2018 13:50] X Y REF_ID X 
[2018 13:50] X Y A 3 
[2018 13:50] X Y C_ID Y 
[2018 13:50] X Y B 4 
[2018 14:00] Z T [2018 14:00] ALI
[2018 14:00] Z T C 3 
[2018 14:00] Z T REF_ID Z 
[2018 14:00] Z T D 1 
[2018 14:00] Z T E 4 
[2018 14:00] Z T C_ID T 

Я пробовал следующее, но оно не работает так, как я хотел.

awk '
BEGIN {FS=" "}
{if ($0 ~ /\[2018/) {flag=1;date_ref=$1;time_ref=$2;}            }
{if ($0 ~ /REF_ID/ ) {t_ref=$2}                   }
{if ($0 ~ /C_ID/ ) {gcid_ref=$2}        }
{if (flag=1) print date_ref,time_ref,t_ref,gcid_ref,$0}
'

вывод, который я получил:

[2018 13:50]   [2018 13:50] ALI
[2018 13:50] X  REF_ID X 
[2018 13:50] X  A 3 
[2018 13:50] X Y C_ID Y 
[2018 13:50] X Y B 4 
[2018 14:00] X Y [2018 14:00] ALI
[2018 14:00] X Y C 3 
[2018 14:00] Z Y REF_ID Z 
[2018 14:00] Z Y D 1 
[2018 14:00] Z Y E 4 
[2018 14:00] Z T C_ID T 

, чтобы решить проблему, которую я считаю нужным поместить данные в буфер, собрать переменную и объединить ее.

Не могли бы вы помочь мне решить эту проблему?проблема? Если бы вы могли объяснить код, который вы предоставляете, это было бы очень полезно.

Ответы [ 2 ]

0 голосов
/ 26 сентября 2018
$ cat tst.awk
/^\[/ {
    prt()
    time = $1 FS $2
}
{
    map[$1] = $2     # save every 1st field to 2nd field mapping,
                     # e.g. map["REF_ID"]="X", map["C_ID"]="Y", etc.
    rec[++numLines] = $0
}
END { prt() }
function prt(   lineNr) {
    for (lineNr=1; lineNr<=numLines; lineNr++) {
        # now just retrieve the 2nd field values by their 1st field names
        print time, map["REF_ID"], map["C_ID"], rec[lineNr]
    }
    numLines = 0
}

$ awk -f tst.awk file
[2018 13:50] X Y [2018 13:50] ALI
[2018 13:50] X Y REF_ID X
[2018 13:50] X Y A 3
[2018 13:50] X Y C_ID Y
[2018 13:50] X Y B 4
[2018 14:00] Z T [2018 14:00] ALI
[2018 14:00] Z T C 3
[2018 14:00] Z T REF_ID Z
[2018 14:00] Z T D 1
[2018 14:00] Z T E 4
[2018 14:00] Z T C_ID T
0 голосов
/ 25 сентября 2018

Полагаю, вас может заинтересовать это:

awk '($1 ~ /^\[/) && record { 
        string= date_ref OFS time_ref OFS t_ref OFS gcid_ref OFS
        gsub(ORS,ORS string, record)
        print string record 
        record=""
     }
    ($1 ~ /^\[/) { date_ref=$1; time_ref=$2 }
    ($1 == "REF_ID") { t_ref=$2 }
    ($1 == "C_ID")   { gcid_ref=$2 }
    { record = record ? record ORS $0 : $0 }
    END { string= date_ref OFS time_ref OFS t_ref OFS gcid_ref OFS
          gsub(ORS,ORS string, record)
          print string record 
    }' <file>

, который выводит:

[2018 13:50] X Y [2018 13:50] ALI
[2018 13:50] X Y REF_ID X 
[2018 13:50] X Y A 3 
[2018 13:50] X Y C_ID Y 
[2018 13:50] X Y B 4 
[2018 14:00] Z T [2018 14:00] ALI
[2018 14:00] Z T C 3 
[2018 14:00] Z T REF_ID Z 
[2018 14:00] Z T D 1 
[2018 14:00] Z T E 4 
[2018 14:00] Z T C_ID T

Идея вышеприведенного кода состоит в том, чтобы встроить record в память перед печатью.что-нибудь.И при построении записи вы выбираете соответствующую информацию, такую ​​как date_ref time_ref, t_ref и gcid_ref

  1. ($1 ~ /^\[/) && record Когда начинается запись (обозначается линиейначиная с [) вы должны выполнять действия с предыдущей записью на основе выбранной вами информации.(если не пусто)

    1. string= date_ref OFS time_ref OFS t_ref OFS gcid_ref OFS: построить string, который вы хотите поместить перед каждой строкой (OFS по умолчанию является пробелом)
    2. gsub(ORS,ORS string, record) подставитьвсе символы новой строки (значение по умолчанию ORS) с ORS string
    3. print string record :: напечатать запись со строкой перед ней, поскольку в первой строке еще нет строки перед ней.
    4. record="" сброс record, поскольку теперь вы строите новую запись.
  2. ($1 ~ /^\[/) { ... }, ($1 == "REF_ID"){...} и ($1 == "C_ID") { }: извлечь соответствующую информацию, когда соблюдены правильные условия (т. е. первое поле равно или соответствует соответствующей вещи).

  3. { record = record ? record ORS $0 : $0 } Построить запись, добавив к ней текущую строку ссимвол новой строки между (ORS по умолчанию является символом новой строки).Обратите внимание, вы должны проверить, если запись пуста, чтобы в начале не было лишних ORS.

  4. END, вам все равно нужно распечатать последнюю запись.Повторите все действия, начиная с шага 1.

...