如何通过awk解析csv文件?

时间:2015-03-07 10:21:32

标签: bash csv awk sed grep

实际上我有csv文件,假设有20个标题,并且它们对于特定记录的下一行中的那些标题具有相应的值。 示例:源文件

Age,Name,Salary
25,Anand,32000

我希望我的输出文件采用这种格式。 示例:输出文件

Age
25
Name
Anand
Salary
32000

这样做是为了使用awk / grep / sed命令吗?

3 个答案:

答案 0 :(得分:1)

我说

awk -F, 'NR == 1 { split($0, headers); next } { for(i = 1; i <= NF; ++i) { print headers[i]; print $i } }' filename

那是

NR == 1 {                       # in the first line
  split($0, headers)            # remember the headers
  next                          # do nothing else
}
{                               # after that:
  for(i = 1; i <= NF; ++i) {    # for all fields:
    print headers[i]            # print the corresponding header
    print $i                    # followed by the field
  }
}

附录:强制性,疯狂的sed解决方案(不推荐用于高效使用;为了娱乐,而非利润而写):

sed 's/$/,/; 1 { h; d; }; G; :a s/\([^,]*\),\([^\n]*\n\)\([^,]*\),\(.*\)/\2\4\n\3\n\1/; ta; s/^\n\n//' filename

其工作原理如下:

s/$/,/         # Add a comma to all lines for more convenient processing
1 { h; d; }    # first line: Just put it in the hold buffer
G              # all other lines: Append hold bufffer (header fields) to the
               # pattern space
:a             # jump label for looping

               # isolate the first fields from the data and header lines,
               # move them to the end of the pattern space
s/\([^,]*\),\([^\n]*\n\)\([^,]*\),\(.*\)/\2\4\n\3\n\1/
ta             # do this until we got them all
s/^\n\n//      # then remove the two newlines that are left as an artifact of
               # the algorithm.

答案 1 :(得分:0)

这是一个awk

awk -F, 'NR==1{for (i=1;i<=NF;i++) a[i]=$i;next} {for (i=1;i<=NF;i++) print a[i] RS $i}' file
Age
25
Name
Anand
Salary
32000

第一个for循环将标头存储在数组a中 第二个for循环从数组a打印带有相应数据的标头。

答案 2 :(得分:0)

使用GNU awk 4. *用于2D数组:

$ awk -F, '{a[NR][1];split($0,a[NR])} END{for (i=1;i<=NF;i++) for (j=1;j<=NR;j++) print a[j][i]}' file
Age
25
Name
Anand
Salary
32000

通常用于转置行和列:

$ cat file
11 12 13
21 22 23
31 32 33
41 42 43

使用GNU awk:

$ awk '{a[NR][1];split($0,a[NR])} END{for (i=1;i<=NF;i++) for (j=1;j<=NR;j++) printf "%s%s", a[j][i], (j<NR?OFS:ORS)}' file
11 21 31 41
12 22 32 42
13 23 33 43

或与任何awk:

$ awk '{for (i=1;i<=NF;i++) a[NR][i]=$i} END{for (i=1;i<=NF;i++) for (j=1;j<=NR;j++) printf "%s%s", a[j][i], (j<NR?OFS:ORS)}' file
11 21 31 41
12 22 32 42
13 23 33 43