使用awk或sed拆分列

时间:2017-03-31 00:07:49

标签: bash perl unix awk sed

我有一个包含以下文字的文件。

  


  aa 6469
  bb 5946
  cc 715

     


  aa 5692

     


  aa 3056
  bb 2893
  cc 1399
  dd 33

我需要以下输出:

  
    

A-Z,aa,bb,cc,dd
    狗,6469,5946,715,0     cat,5692,0,0,0     Bird,3056,2893,1399,33

  

我试过了: awk'{$ 1 = $ 1} 1'OFS =“,”RS = 但是没有给出我需要的格式。

提前感谢您的帮助。

克里斯

3 个答案:

答案 0 :(得分:2)

使用Perl

perl -00 -nE'
    ($t, %p) = split /[\n\s]/; $h{$t} = {%p};     # Top line, Pairs on lines
    $o{$t} = ++$c;                                # remember Order
    %k = map { $_, 1} keys %p;                    # find full set of subKeys
    }{                                            # END block starts
    say join ",", "A-Z", sort keys %k;
    for $t (sort { $o{$a} <=> $o{$b} } keys %h) { 
        say join ",", $k, map { ($h{$k}{$_} // 0) } sort keys %k;
    }
' data.txt

以原始顺序打印

A-Z,aa,bb,cc,dd
dog,6469,5946,715,0
cat,5692,0,0,0
Bird,3056,2893,1399,33

答案 1 :(得分:1)

这里有一个解决方案,它适用于您的输入,但要求您事先知道列名称,并且列名称是以第一列名称开头的已排序的完整范围给出的(所以不像 aa,cc bb,aa bb,cc )并且每个段落后跟一个空行。如果您没有恰好有四个数字列,则还需要调整脚本:

echo 'A-Z, aa, bb, cc, dd';sed -e '/./{s/.* //;H;d};x;s/\n/, /g;s/, //;s/$/, 0, 0, 0, 0/;:a;s/,[^,]*//5;ta' file

如果您需要查找sed命令,可以查看info sed,尤其是 3.5常用命令

答案 2 :(得分:0)

awk救援!

awk -v OFS=, 'NF==1 {h[++c]=$1} 
              NF==2 {v[c,$1]=$2; ks[$1]} 
              END   {printf "%s", "A-Z"; 
                     for(k in ks) printf "%s", OFS k; 
                     print ""; 
                     for(i=1;i<=c;i++) 
                       {printf "%s", h[i]; 
                        for(k in ks) printf "%s", OFS v[i,k]+0; 
                        print ""}}' file'

列的顺序是随机的。