根据列属性重复行

时间:2018-05-15 20:38:02

标签: awk

使用csv文件,我需要生成一个类似于所需输出的文件,目的是使用第3列重复列1和2根据第3列中的时间进行分离)。例子

39823,39828:38466-38896/2(1-216)
39840:38466-38896/2(217-432)
39852:38466-38896/2(433-648)

在第3列中有3次(...),对于第1列和第2列应该是3次重复。

这里是输入文件

21,39823,39828:38466-38896/2(1-216) 39840:38466-38896/2(217-432) 39852:38466-38896/2(433-648),0
22,39827,39828:38466-38896/2(1-216) 39840:38466-38896/2(217-432) 39852:38466-38896/2(433-648) 39864:38466-38896/2(649-864),0
23,39825,39828:38466-38896/2(1-216) 39840:38466-38896/2(217-432) 39852:38466-38896/2(433-648), 39852:38000-90000/2(433-648)
24,39827,39828:38466-39196/2(1-366) 39840:38466-39196/2(367-732) 39852:38466-39196/2(733-1098),0

输出所需

21  39823   39828:38466-38896/2(1-216)
21  39823   39840:38466-38896/2(217-432)
21  39823   39852:38466-38896/2(433-648)
22  39827   39828:38466-38896/2(1-216)
22  39827   39840:38466-38896/2(217-432)
22  39827   39852:38466-38896/2(433-648)
22  39827   39864:38466-38896/2(649-864)
23  39825   39828:38466-38896/2(1-216)
23  39825   39840:38466-38896/2(217-432)
23  39825   39852:38466-38896/2(433-648)
**23  39825   39852:38000-90000/2(433-648)**
24  39827   39828:38466-39196/2(1-366)
24  39827   39840:38466-39196/2(367-732)
24  39827   39852:38466-39196/2(733-1098)

提前致谢

2 个答案:

答案 0 :(得分:1)

Awk 解决方案:

awk -F',|[[:space:]]+' '{ for (i=3; i<=NF; i++) print $1, $2, $i }' OFS='\t' file

输出:

21  39823   39828:38466-38896/2(1-216)
21  39823   39840:38466-38896/2(217-432)
21  39823   39852:38466-38896/2(433-648)
22  39827   39828:38466-38896/2(1-216)
22  39827   39840:38466-38896/2(217-432)
22  39827   39852:38466-38896/2(433-648)
22  39827   39864:38466-38896/2(649-864)
23  39825   39828:38466-38896/2(1-216)
23  39825   39840:38466-38896/2(217-432)
23  39825   39852:38466-38896/2(433-648)
24  39827   39828:38466-39196/2(1-366)
24  39827   39840:38466-39196/2(367-732)
24  39827   39852:38466-39196/2(733-1098)

答案 1 :(得分:1)

您能否请关注awk并告诉我这是否对您有所帮助。

awk -v s1="**" -F' |,' '{nf=$NF==0||!$NF?NF-1:NF;for(i=3;i<=nf;i++){if($i){match($i,/\(.*\)/);val=substr($i,RSTART,RLENGTH);printf("%s%s",++a[val]>3? s1 $1 OFS $2 OFS $i s1:$1 OFS $2 OFS $i,ORS)}}}'  Input_file

现在也添加非单线形式的解决方案。

awk -v s1="**" -F' |,' '
{
  nf=$NF==0||!$NF?NF-1:NF;
  for(i=3;i<=nf;i++){
     if($i){
       match($i,/\(.*\)/);
       val=substr($i,RSTART,RLENGTH);
       printf("%s%s",++a[val]>3? s1 $1 OFS $2 OFS $i s1:$1 OFS $2 OFS $i,ORS)
     }
  }
}'   Input_file