使用awk多个字段进行分离和重新排序

时间:2018-07-01 22:59:21

标签: bash awk command-line

我有一个文件

input.txt

04120;2017-12-27;object1;2017-12-27;object2;2017-12-27;object3;2017-12-27;object4;2017-12-28;XXXXXX1;2017-12-28;XXXXXX2;2018-03-06;object5;2018-03-06;object6
06499;2018-05-30;object1;2018-05-30;object2;2018-05-30;object3;2018-05-30;XXXXXX1;2018-05-31;object4
04123;2017-12-28;object1;2017-12-28;XXXXXX1;2018-04-05;object2
04520;2018-02-11;object1;2018-02-11;object2;2018-02-16;XXXXXX1;2018-03-10;object3
04510;2018-02-09;object1;2018-02-09;object2;2018-02-09;XXXXXX1;2018-02-16;XXXXXX2;2018-04-04;object3

我的日志具有不同的字段号,以“;”分隔。如示例所示,我有7,9,11或17个字段 我需要在该行的末尾保存第一个条目XXXXXX及其日期,以及之前的对象。从行的中间删除这些字段

例如:

from 
04123;2017-12-28;<b>object1;2017-12-28;XXXXXX1</b>;2018-04-05;object2
to
04123;2017-12-28;object1;2018-04-05;object2;<b>2017-12-28;object1;XXXXXX1</b>

输出看起来像这样:

04120;2017-12-27;object1;2017-12-27;object2;2017-12-27;object3;2017-12-27;object4;2018-03-06;object5;2018-03-06;object6;2017-12-28;object4;XXXXXX1
06499;2018-05-30;object1;2018-05-30;object2;2018-05-30;object3;2018-05-31;object4;2018-05-30;object3;XXXXXX1
04123;2017-12-28;object1;2018-04-05;object2;2017-12-28;object1;XXXXXX1
04520;2018-02-11;object1;2018-02-11;object2;2018-03-10;object3;2018-02-16;object2;XXXXXX1
04510;2018-02-09;object1;2018-02-09;object2;2018-04-04;object3;2018-02-09;object2;XXXXXX1

如何在bash中执行命令行?尝试用awk,但我还没有得到

2 个答案:

答案 0 :(得分:2)

编辑: 现在也正在改进我以前的解决方案。

awk --re-interval '
match($0,/object[0-9]+;[0-9]{4}\-[0-9]{2}\-[0-9]{2};X+[0-9]+.*X+[0-9]+;[0-9]{4}\-[0-9]{2}\-[0-9]{2}|object[0-9]+;[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],array[num],substr($0,RSTART+RLENGTH+1),array[2],array[1],array[3]
}
'  OFS=";"  Input_file

能否请您尝试以下操作,如果有帮助,请告诉我。

awk --re-interval '
match($0,/object[0-9]+;[0-9]{4}\-[0-9]{2}\-[0-9]{2};X+[0-9]+.*X+[0-9]+;[0-9]{4}\-[0-9]{2}\-[0-9]{2}|object[0-9]+;[0-9]{4}\-[0-9]{2}\-[0-9]{2};X+[0-9]+;[0-9]{4}\-[0-9]{2}\-[0-9]{2}/){
  value1=value2=substr($0,RSTART,RLENGTH);
  sub(/.*;/,"",value1);
  split(value2,array,";");
  print substr($0,1,RSTART-1) array[1],value1,substr($0,RSTART+RLENGTH+1),array[2],array[1],array[3]
}
'  OFS=";"  Input_file

输出如下。

04120;2017-12-27;object1;2017-12-27;object2;2017-12-27;object3;2017-12-27;object4;2018-03-06;object5;2018-03-06;object6;2017-12-28;object4;XXXXXX1
06499;2018-05-30;object1;2018-05-30;object2;2018-05-30;object3;2018-05-31;object4;2018-05-30;object3;XXXXXX1
04123;2017-12-28;object1;2018-04-05;object2;2017-12-28;object1;XXXXXX1
04520;2018-02-11;object1;2018-02-11;object2;2018-03-10;object3;2018-02-16;object2;XXXXXX1
04510;2018-02-09;object1;2018-02-09;object2;2018-04-04;object3;2018-02-09;object2;XXXXXX1

注意: :只有旧版本的awk具有--re-interval,如果您的awk版本是新的,则可以将其删除

答案 1 :(得分:2)

使用GNU awk作为match()gensub()的第三个参数:

$ cat tst.awk
match($0,/(;[^;]+)(;[^;]+)(;XXX[^;]+)(.*)/,a) {
   $0 = substr($0,1,RSTART-1) a[1] gensub(/;[^;]+;XXX[^;]+/,"","g",a[4]) a[2] a[1] a[3]
}
{ print }

$ awk -f tst.awk file
04120;2017-12-27;object1;2017-12-27;object2;2017-12-27;object3;2017-12-27;object4;2018-03-06;object5;2018-03-06;object6;2017-12-28;object4;XXXXXX1
06499;2018-05-30;object1;2018-05-30;object2;2018-05-30;object3;2018-05-31;object4;2018-05-30;object3;XXXXXX1
04123;2017-12-28;object1;2018-04-05;object2;2017-12-28;object1;XXXXXX1
04520;2018-02-11;object1;2018-02-11;object2;2018-03-10;object3;2018-02-16;object2;XXXXXX1
04510;2018-02-09;object1;2018-02-09;object2;2018-04-04;object3;2018-02-09;object2;XXXXXX1