AWK обрабатывает данные до следующего матча - PullRequest
0 голосов
/ 22 мая 2018

Я пытаюсь обработать файл с помощью awk.пример данных:

   233;20180514;1;00;456..;m
   233;1111;2;5647;6754;..;n
   233;1111;2;5647;2342;..;n
   233;1111;2;5647;p234;..;n
   233;20180211;1;00;780..;m
   233;1111;2;5647;3434;..;n
   233;1111;2;5647;4545;..;n
   233;1111;2;5647;3453;..;n

Проблема состоит в том, что мне нужно скопировать второй столбец записи, соответствующей "1; 00;"до следующих записей до следующего "1; 00;"сопоставьте, а затем скопируйте второй столбец этой записи до следующего "1; 00;"матч.Шаблон совпадения "1; 00;"может измениться.Можно сказать "2; 20;",В этом случае мне нужно скопировать второй столбец, пока не появится «1; 00;»или "2; 20;"match.

Я могу сделать это, используя цикл while, но мне действительно нужно сделать это, используя awk или sed, поскольку файл огромен и может занять много времени.

Ожидаемый результат:

   233;20180514;1;00;456..;m
   233;20180514;1111;2;5647;6754;..;n+1
   233;20180514;1111;2;5647;2342;..;n+1
   233;20180514;1111;2;5647;p234;..;n+1
   233;20180211;1;00;780..;m
   233;20180211;1111;2;5647;3434;..;n+1
   233;20180211;1111;2;5647;4545;..;n+1
   233;20180211;1111;2;5647;3453;..;n+1

Заранее спасибо.

1 Ответ

0 голосов
/ 22 мая 2018

РЕДАКТИРОВАТЬ: Поскольку OP изменили образец рассматриваемого Input_file, поэтому добавьте код в соответствии с новым образцом сейчас.

awk -F";" '
length($2)==8 && !($3=="1" && $4=="00"){
   flag=""}
($3=="1" && $4=="00"){
   val=$2;
   $2="";
   sub(/;;/,";");
   flag=1;
   print;
   next
}
flag{
   $2=val OFS $2;
   $NF=$NF"+1"
}
1
' OFS=";"  Input_file

В основном проверка длины2-е поле из 8-го и 3-го и 4-го полей НЕ являются условиями 1 и 0, а не проверяют ;1;0.



Если ваш фактический Input_file такой же, как показано в примерах, тогдаможет помочь вам.

awk -F";" 'NF==5 || !/pay;$/{flag=""} /1;00;$/{val=$2;$2="";sub(/;;/,";");flag=1} flag{$2=val OFS $2} 1' OFS=";"  Input_file

Объяснение:

awk -F";" '         ##Setting field separator as semi colon for all the lines here.
NF==5 || !/pay;$/{  ##Checking condition if number of fields are 5 on a line OR line is NOT ending with pay; if yes then do following.
  flag=""}          ##Setting variable flag value as NULL here.
/1;00;$/{           ##Searching string /1;00; at last of a line if it is found then do following:
  val=$2;           ##Creating variable named val whose value is $2(3nd field of current line).
  $2="";            ##Nullifying 2nd column now for current line.
  sub(/;;/,";");    ##Substituting 2 continous semi colons with single semi colon to remove 2nd columns NULL value.
  flag=1}           ##Setting value of variable flag as 1 here.
flag{               ##Checking condition if variable flag is having values then do following.
  $2=val OFS $2}    ##Re-creating value of $2 as val OFS $2, basically adding value of 2nd column of pay; line here.
1                   ##awk works on concept of condition then action so mentioning 1 means making condition TRUE and no action mentioned so print will happen of line.
' OFS=";" Input_file ##Setting OFS as semi colon here and mentioning Input_file name here.
...