使用awk重新排序列

时间:2016-10-16 07:33:26

标签: bash awk sed

我正在尝试使用awk重新排序列,sed ...但我找不到正确的答案, 基本上,我想重新排序来自:

的值
time 012016 022016 032016 04216

John 231 321 121 432

Mary 456 213 654 735

Charles 325 867 984 235

为:

time John Mary Charles

012016 231 456 325

022016 321 213 867

032016 121 654 984

042016 432 735 235

我尝试使用类似的东西,但我错过了数字:

awk '{print $1}' ./database.dat | paste -d,  -s 

输出:

time John Mary Charles

4 个答案:

答案 0 :(得分:1)

使用ghostdog74's awk script三次转置文件:

#!/bin/bash

transpose () {
  awk '
  { 
    for (i=1; i<=NF; i++)  {
      a[NR,i] = $i
    }
  }
  NF>p { p = NF }
  END {    
    for(j=1; j<=p; j++) {
      str=a[1,j]
      for(i=2; i<=NR; i++){
        str=str" "a[i,j];
      }
      print str
    }
  }'
}

transpose | transpose | transpose

用法:./this_script.sh < filename

输出:

time John Mary Charles
012016 231 456 325
022016 321 213 867
032016 121 654 984
04216 432 735 235

我假设你的文件没有空行。

或修改ghostdog74的脚本以向其他方向旋转。

答案 1 :(得分:1)

希望这是你正在寻找的东西:

awk脚本

awk '{for(i=1;i<=NF;i++){val[NR][i]=$i}}
     NR==FNR{fc=NF}
     END{for(i=1;i<=fc;i++){
     for(rec=1;rec<=FNR;rec++){printf "%s%s",val[rec][i],(rec<FNR)?"\t":ORS}
     }}' filename

<强>输出

time        John    Mary    Charles
012016      231     456     325
022016      321     213     867
032016      121     654     984
04216       432     735     235

假设:文件中的每条记录都有相同数量的字段

答案 2 :(得分:1)

$ cat ip.txt 
time 012016 022016 032016 04216
John 231 321 121 432
Mary 456 213 654 735
Charles 325 867 984 235

使用trwcpr

$ tr ' ' '\n' < ip.txt | pr -$(wc -l < ip.txt)t
time          John          Mary          Charles
012016        231           456           325
022016        321           213           867
032016        121           654           984
04216         432           735           235


使用perl时,应该比tr, wc, pr mash

更快
$ perl -lane '                                                                                                      
push(@a, @F);
END
{
    $r = $.; $c = $#F + 1;
    foreach $i (0..$#F)
    {
        print join "\t", @a[map {$i + $_*$c} 0..$r];
    }
}' ip.txt
time    John    Mary    Charles 
012016  231 456 325 
022016  321 213 867 
032016  121 654 984 
04216   432 735 235 
  • 输入行在空格上分割,并保存在@F数组中。该数组连接到@a数组
  • 的每一行
  • 处理完整个文件后,$.将在输入文件中包含多行。 $#F给出@F数组
  • 的最后一个元素的索引
  • 然后以所需格式打印

答案 3 :(得分:1)

来自BSD的rs实用程序(使用apt-get install rs在Ubuntu中获得)。

$ rs -t 5
time 012016 022016 032016 04216

John 231 321 121 432

Mary 456 213 654 735

Charles 325 867 984 235
[Ctrl-D][Enter]
time     John     Mary     Charles
012016   231      456      325
022016   321      213      867
032016   121      654      984
04216    432      735      235

使用TXR Lisp进行转置:

$ txr -e '(put-lines (mapcar (op cat-str @1 " ") (transpose (build (awk (f (add f)))))))' data
time John Mary Charles
012016 231 456 325
022016 321 213 867
032016 121 654 984
04216 432 735 235