Shell - 行列转换

作者: 码农郭 | 来源:发表于2019-06-14 17:48 被阅读0次

    在日常文本的处理中,我们经常会碰见行列转换的情况,以下为几种常见的行列转换命令:

    方案一

    基本思路:将所有内容存储到一个二维数组中,之后按列输出每一行

     cat file.txt | awk 'BEGIN{c=0;} {for(i=1;i<=NF;i++) {num[c,i] = $i;} c++;} END{ for(i=1;i<=NF;i++){str=""; for(j=0;j<NR;j++){ if(j>0){str = str" "} str= str""num[j,i]}printf("%s\n", str)} }' 
    

    如果想使用tab键分开:

    cat file.txt | awk 'BEGIN{c=0;} {for(i=1;i<=NF;i++) {num[c,i] = $i;} c++;} END{ for(i=1;i<=NF;i++){str=""; for(j=0;j<NR;j++){ if(j>0){str = str" "} str= str"\t"num[j,i]}printf("%s\n", str)} }' 
    

    另一种写法

    cat file.txt | awk '{for(i=1;i<=NF;i=i+1){a[NR,i]=$i}}END{for(j=1;j<=NF;j++){str=a[1,j];for(i=2;i<=NR;i++){str=str " " a[i,j]}print str}}'
    

    方案二

    使用一维数组,记录每一列的组合串;当是第一行时赋值,否则都是累加,即字符串拼接

    cat file.txt | awk '{ for(i=1;i<=NF;i++){ if(NR==1){ arr[i]=$i; }else{ arr[i]=arr[i]" "$i; } } } END{ for(i=1;i<=NF;i++){ print arr[i]; } }' 
    

    同样,tab键分割:

    cat file.txt | awk '{ for(i=1;i<=NF;i++){ if(NR==1){ arr[i]=$i; }else{ arr[i]=arr[i]"\t"$i; } } } END{ for(i=1;i<=NF;i++){ print arr[i]; } }' 
    
    awk参数解析

    NR - Number of Record :当前处理的行是第几行(因为awk是流处理工具,一行一行处理的,所以NR在不停的自增1);END里面引用的NR,是处理完文本后的NR
    FNR - File Number of Record :当前处理的行是当前处理文件的第几行
    NF - Number of Fileds:当前行有多少列数据(这个在每行都会根据设定的分割符重新计算,默认分割符是任意连续的多个空白符)

    实例解析

    文件: expression_mRNA_17-Aug-2014.txt

    $cat expression_mRNA_17-Aug-2014.txt* | sed -n '1,10p' | cut -f 1-10 | en

      1         tissue  sscortex        sscortex        sscortex        sscortex        sscortex        sscortex        sscortex        ca1hippocampus
      2         group # 1       1       1       1       1       1       1       1
      3         total mRNA mol  21580   21748   31642   32916   21531   24799   31406   20389
      4         well    11      95      33      42      48      13      50      66
      5         sex     1       -1      -1      1       1       -1      1       -1
      6         age     21      20      20      21      25      20      25      23
      7         diameter        0       9.56    11.1    11.7    11      11.9    11.3    10.9
      8 (none)  cell_id 1772071015_C02  1772071017_G12  1772071017_A05  1772071014_B06  1772067065_H06  1772071017_E02  1772067065_B07  1772067060_B09
      9 (none)  level1class     interneurons    interneurons    interneurons    interneurons    interneurons    interneurons    interneurons    interneurons
     10 (none)  level2class     Int10   Int10   Int6    Int10   Int9    Int9    Int10   Int9
    

    $cat expression_mRNA_17-Aug-2014.txt* | sed -n '1,10p' | cut -f 1-10 | cut -f 2- | awk '{ for(i=1;i<=NF;i++){ if(NR==1){ arr[i]=$i; }else{ arr[i]=arr[i]"\t"$i; } } } END{ for(i=1;i<=NF;i++){ print arr[i]; } }' | en

      1 tissue  group   total   well    sex     age     diameter        cell_id level1class     level2class
      2 sscortex        #       mRNA    11      1       21      0       1772071015_C02  interneurons    Int10
      3 sscortex        1       mol     95      -1      20      9.56    1772071017_G12  interneurons    Int10
      4 sscortex        1       21580   33      -1      20      11.1    1772071017_A05  interneurons    Int6
      5 sscortex        1       21748   42      1       21      11.7    1772071014_B06  interneurons    Int10
      6 sscortex        1       31642   48      1       25      11      1772067065_H06  interneurons    Int9
      7 sscortex        1       32916   13      -1      20      11.9    1772071017_E02  interneurons    Int9
      8 sscortex        1       21531   50      1       25      11.3    1772067065_B07  interneurons    Int10
      9 ca1hippocampus  1       24799   66      -1      23      10.9    1772067060_B09  interneurons    Int9
    

    巨人的肩膀

    Shell练习 行列转换
    Linux 文本行列转换

    相关文章

      网友评论

        本文标题:Shell - 行列转换

        本文链接:https://www.haomeiwen.com/subject/ojeqqqtx.html