使用shell脚本进行CSV操作

时间:2017-02-24 14:28:32

标签: linux shell csv unix data-manipulation

我有一个像这样的CSV文件

Country,Jan1,Feb1,.....,Dec16 
India,100,2000,........,1500
China,4768,46783,.......,3000
Canada,4789,7393,.......,9843

我想以下面给出的格式获得输出

India,100,Jan1 
China,4768,Jan1
Canada,4789,Jan1
India,2000,Feb1
China,46783,Feb1
Canada,7393,Feb1
.
.
.
India,1500,Dec16
China,3000,Dec16
Canada,9843,Dec16

有谁可以分享一下,Shell脚本中的上述内容是如何实现的?

谢谢和问候, 罗宾大卫

1 个答案:

答案 0 :(得分:1)

你可以尝试这个awk脚本:

<强> script.awk

const

您运行它:BEGIN { ctrNo = 1 } NR==1 { # store time colheaders for( c = 2 ; c <= NF; c++ ) TimeMember[ c-1] = $c; next } { # for NR > 1: store value under key country and TimeMember ctry = $1 for( c = 2; c<= NF; c++ ) { key = sprintf("%s,%s", ctry, TimeMember[ c - 1 ] ) values[ key ] = $c } if( !( ctry in seen) ) { seen[ ctry ] = 1; countries [ ctrNo++ ] = ctry } } END { OFS=FS for( c = 1; c <= length( TimeMember ) ; c++ ){ for( ctr = 1; ctr <= length( countries ) ; ctr++ ) { key = sprintf("%s,%s", countries[ ctr], TimeMember[ c ] ) print countries[ ctr], values[ key ], TimeMember[ c ] } } }

<强>解释

  • awk -F, -f script.awk yourfile部分初始化变量
  • 对第一行执行BEGIN动作,它存储第一行的所有TimeMembers。 NR==1会忽略其他操作被跳过。
  • 以下Action分析数据行,并将每个TimeColumn的值与next中的CountryMember一起存储。每个新国家/地区都会获得values操作
  • 中输出期间使用的新序列号
  • END动作涉及打印存储的信息。它从第一行循环到不同的TimeMembers,并从数据行第一列的Country Dimension遍历每个成员。