首页 > 解决方案 > 在数组中找到匹配后如何转置数据

问题描述

我希望数据是来自 xml 数据的 csv 格式

xml data to test is available in this question extract data between tags <t> </t>

注意: xml 文件中的数据可能会有所不同,标题也会有所不同

在这个 xml 中,它们是 3 个标题 ->NAME,AGE,COURSE

我使用下面的命令来获取水平格式的数据,全部在一行中:

awk -F'(</*t>|</*t>)' 'NF>1{for(i=2;i<NF; i=i+2) printf("%s%s", $i, (i+1==NF)?ORS:OFS)}' OFS=',' demo.xml

运行上面的命令后,下面是输出 "NAME","Vikas","Vijay","Vilas","AGE","24","34","35","COURSE","MCA","彩信","MBA"

我如何尝试实现逻辑

从用户那里获取参数,有多少个标题值将是他们的

在上面的 xml 中,它们是 3 个标题 ->NAME,AGE,COURSE

header_count=3

所以 3 个标题意味着将有 3 个值,例如:HEADER + 3值 NAME、Vikas、Prabhas、Arjun -> 这将转置到下面

输出 :

NAME,
Vikas,
Prabhas,
Arjun,

标题值AGE ->AGE + 3值也是如此

AGE,25,34,21  will be transpose to vertical 

AGE
25
34
21

标题值COURSE -> COURSE + 3values也是如此

COURSE,MCA,MBA,MMS  will be transpose to vertical 

COURSE
MCA
MBA
MMS

**综合姓名、年龄、课程的所有数据后的预期输出**

NAME,AGE,Course
Vikas,"25",MCA
Prabhash,"34",MBA
Arjun,"21",MMS

标签: shellunix

解决方案


使用您显示的示例,请尝试以下操作。用 GNU 编写和测试awk,应该可以在任何awk.

awk '
BEGIN{
  FS=OFS=","
}
{
  for(i=1;i<=NF;i++){
    if($i~/^"NAME"/){
      found1=1
      found2=found3=""
    }
    if($i~/^"AGE"$/){
      found1=found2=""
      found2=1
    }
    if($i~/^"COURSE"$/){
      found1=found2=""
      found3=1
    }
    if(found1){
      name[++count1]=$i
    }
    if(found2){
      age[++count2]=$i
    }
    if(found3){
      course[++count3]=$i
    }
  }
}
END{
  if(count1>=count2 && count1>=count3){ max=count1 }
  if(count2>=count1 && count2>=count3){ max=count2 }
  if(count3>=count1 && count3>=count2){ max=count3 }
  for(i=1;i<=max;i++){
      print (name[i]?name[i]:"NA",age[i]?age[i]:"NA",course[i]?course[i]:"NA")
  }
}
'  Input_file

推荐阅读