awk日志具有多个字段-分开并重新排序

时间:2018-07-03 00:55:54

标签: regex bash shell awk command-line

我有一个文件

input.txt

ID04120;2017-12-27;Office One;2017-12-27;Merchan Dep;2017-12-27;Sales Team 1;2017-12-27;Merchan Dep;2017-12-28;XXX4615;2017-12-28;XXX4615;2018-03-06;Office One;2018-03-06;Office One
ID04123;2017-12-28;Office One;2017-12-28;XXX4616;2018-04-05;Office One
ID04130;2017-12-29;Office One;2017-12-29;Room Fabric;2017-12-29;Support;2017-12-29;XXX4497;2018-01-17;Office One;2018-01-17;XXX4497;2018-01-17;Sales Team 3;2018-01-17;XXX4497;2018-03-13;Dev-sales-id;2018-03-14;XXX4497;2018-03-16;Dev Fabric
ID04266;2018-01-13;Office One;2018-01-13;XXX4186;2018-02-20;XXX4186;2018-02-22;XXX4186;2018-03-01;Office One

我的日志具有不同的字段号,可能有7个或更多字段,不是一个常量,用“;”分隔

在示例中,我可以有7,11,17或23个字段

我需要获取第一个条目XXX [0-9] {4}及其日期(上一个字段),以及该行之前的公司部门,然后在行尾对其进行排序。

如果不需要,则不需要条目XXX [0-9] {4}及其日期(上一个字段)和其他条目XXX [0-9] {4}及其日期(上一个字段)

例如:

来自
ID04123; 2017-12-28; Office One; 2017-12-28; XXX4616 ; 2018-04-05; Office One


ID04123; 2017-12-28; Office One; 2018-04-05; Office One; 2017-12-28; Office One; XXX4616

输出看起来像这样:

ID04120;2017-12-27;Office One;2017-12-27;Merchan Dep;2017-12-27;Sales Team 1;2017-12-27;Merchan Dep;2018-03-06;Office One;2018-03-06;Office One;2017-12-28;Merchan Dep;XXX4615
ID04123;2017-12-28;Office One;2018-04-05;Office One;2017-12-28;Office One;XXX4616
ID04130;2017-12-29;Office One;2017-12-29;Room Fabric;2017-12-29;Support;2018-01-17;Office One;2018-01-17;Sales Team 3;2018-03-13;Dev-sales-id;2018-03-16;Dev Fabric;2017-12-29;Support;XXX4497
ID04266;2018-01-13;Office One;2018-03-01;Office One;2018-01-13;Office One;XXX4186

我可以尝试

awk --re-interval '
match($0,/[[:alnum:]]+;[0-9]{4}\-[0-9]{2}\-[0-9]{2};XXX+[0-9]{4}+.*XXX+[0-9]{4}+;[0-9]{4}\-[0-9]{2}\-[0-9]{2}|[[:alnum:]]+;[0-9]{4}\-[0-9]{2}\-[0-9]{2};XXX+[0-9]{4}+;[0-9]{4}\-[0-9]{2}\-[0-9]{2}/){
value2=substr($0,RSTART,RLENGTH);
num=split(value2,array,";");
print substr($0,1,RSTART-1) array[1],array[num],substr($0,RSTART+RLENGTH+1),array[2],array[1],array[3]
}'  OFS=";" input.txt

但是没有用

1 个答案:

答案 0 :(得分:1)

编辑: :似乎OP可能在一行中出现多次正则表达式,因此根据显示的示例,将代码更改为如下所示以获取所需的输出。

awk -v s1=";" --re-interval -F";" '
match($0,/[a-zA-Z ]+;[0-9]{4}\-[0-9]{2}\-[0-9]{2};X+[0-9]+.*X+[0-9]+;[0-9]{4}\-[0-9]{2}\-[0-9]{2}|[a-zA-Z ]+;[0-9]{4}\-[0-9]{2}\-[0-9]{2};X+[0-9]+;[0-9]{4}\-[0-9]{2}\-[0-9]{2}/){
   value2=value3=substr($0,RSTART,RLENGTH);
   split(value3,array,";");
   gsub(/;[0-9]{4}\-[0-9]{2}\-[0-9]{2};X+[0-9]+/,"",value2);
   print substr($0,1,RSTART-1) value2 s1 substr($0,RSTART+RLENGTH+1) s1 array[2] s1 array[1] s1 array[3];
   value2=""
}'  Input_file


似乎提到的正则表达式不起作用,因为您在上一篇文章中提到的字符串object更改为其他字符串,因此我将正则表达式从匹配的字符串object更改为[a-zA-Z]+,如下工作正常。

awk -v s1=";" --re-interval -F";" '
match($0,/[a-zA-Z]+;[0-9]{4}\-[0-9]{2}\-[0-9]{2};X+[0-9]+.*X+[0-9]+;[0-9]{4}\-[0-9]{2}\-[0-9]{2}|[a-zA-Z]+;[0-9]{4}\-[0-9]{2}\-[0-9]{2};X+[0-9]+;[0-9]{4}\-[0-9]{2}\-[0-9]{2}/){
  value2=substr($0,RSTART,RLENGTH);
  num=split(value2,array,";");
  print substr($0,1,RSTART-1) array[1] s1 array[num] s1 substr($0,RSTART+RLENGTH+1) s1 array[2] s1 array[1] s1 array[3]
}'  Input_file