如何在bash / awk / other中进行转置

时间:2015-05-25 21:01:59

标签: bash awk transpose

如何转置以下数据

ServieFile

所以它看起来像这样:

colA    colB    colC    colD
val1    val2    val3    val4
val5    val6    val7    val8

此数据以制表符分隔,但也可以用逗号分隔。

我可以在excel中很容易地做到这一点,但我想知道如何使用awk或类似的东西在bash中做到这一点?

EDIT1

我可以使用空格

colA    val1    val5
colB    val2    val6
colC    val3    val7
colD    val4    val8

但它与逗号分隔文件不一样

$ cat testdata2_withspace.txt
colA colB colC colD
val1 val2 val3 val4
val5 val6 val7 val8

$ ./transpose3.sh testdata2_withspace.txt
colA val1 val5
colB val2 val6
colC val3 val7
colD val4 val8

3 个答案:

答案 0 :(得分:2)

$ cat tst.awk
{ for (i=1; i<=NF; i++) cell[NR,i]=$i }
END {
    for (row=1; row<=NF; row++) {
        for (col=1; col<=NR; col++) {
            printf "%s%s", cell[col,row], (col<NR?OFS:ORS)
        }
    }
}

$ awk -f tst.awk file
colA val1 val5
colB val2 val6
colC val3 val7
colD val4 val8

要使用逗号而不是空格作为分隔符,请在开头添加BEGIN{ FS=OFS="," }

答案 1 :(得分:0)

可以使用awk脚本from here

#!/bin/bash 

transpose() 
{ 
  awk ' 
      BEGIN {
          FS = ",";
          OFS = ",";
      }

      { 
              if (max_nf<NF) 
                    max_nf=NF 
              max_nr=NR 
              for (x=1; x<=NF; ++x) 
                     vector[x, NR]=$x 
      } 

      END { 
              for (x=1; x<=max_nf; ++x) { 
                   for (y=1; y<=max_nr; ++y) 
                        printf("%s ", vector[x, y]) 
                   printf("\n") 
               } 
          }'  ${1} 
} 

transpose ${1} 

答案 2 :(得分:-1)

由于问题标题包含&#34; / other&#34;我想发布一个Python + Bash答案。

以下适用于制表符/空格分隔文件,CSV

所需的次要调整
$ trans () { python2 -c 'print "\n".join("\t".join(t)for t in zip(*[l.split()for l in open("'"$1"'")]))' ; }
$ cat test2.csv
Roll_num Marks Grade
1        75    A
2        60    C
27       68    B
61       45    E
$ trans test2.csv 
Roll_num        1       2       27      61
Marks   75      60      68      45
Grade   A       C       B       E

如定义的那样,shell函数应该对于&#34; fun ny&#34;而言应该是健壮的。文件名

$ cp test2.csv fun\ ny
$ trans fun\ ny
Roll_num        1       2       27      61
Marks   75      60      68      45
Grade   A       C       B       E
$

附录

以下是CSV文件

所需的次要调整
$ trans, () { python2 -c'print"\n".join(",".join(r)for r in zip(*[[i.strip()for i in l.strip().split(",")]for l in open("'"$1"'")]))'; }
$ cat test111.csv
Sales #, Date, Tel Number, Comment
393ED3, 5/12/2010, 5555551212, left message
585E54, 6/15/2014, 5555551213, voice mail
585868, 8/16/2010, , number is 5555551214
$ trans, test111.csv
Sales #,393ED3,585E54,585868
Date,5/12/2010,6/15/2014,8/16/2010
Tel Number,5555551212,5555551213,
Comment,left message,voice mail,number is 5555551214