【问题标题】:Merge files with different columns and rows linux合并具有不同列和行的文件linux
【发布时间】:2017-04-18 20:35:01
【问题描述】:

我有一些需要加入的文件,我已经寻找了一些解决方案,但它们不符合我的需要,我有以下文件

一个.csv

日期|A|B|C|D
15-03-2017|1|3|9|4

和 b.csv

日期|A|C|D|E
16-03-2017|2|9|3|4

我想得到下一个输出:

日期|A|B|C|D|E
15-03-2017|1|3|9|4|0
16-03-2017|2|0|9|3|4

感谢任何见解或建议!

编辑: 谢谢大家

这些文件示例并不总是相同的 有时它可以有 10 到 50 列和 1 到 30 行(日期)

【问题讨论】:

  • 有趣的任务,初始文件可以有多行(多于两行)吗?
  • 这不是join 的任务。请删除标签。

标签: awk


【解决方案1】:

这样的……

awk 'BEGIN  {FS=OFS="|"} 
     FNR==1 {split($0,h); next} 
            {c++; 
             for(i=1;i<=NF;i++) 
                {a[h[i],c]=$i; 
                 hall[h[i]]}} 
     END    {for(k in hall) printf "%s", k OFS; 
             print "";
             for(i=1;i<=c;i++) 
                {for(k in hall) printf "%s", ((k,i) in a?a[k,i]:0) OFS; 
                 print ""}}' file1 file2

A|B|C|D|E|date |
1|3|9|4|0|15-03-2017|
2|0|9|3|4|16-03-2017|

您可以使用一些额外的代码对列重新排序,但也许会出现更好的解决方案...

【讨论】:

  • OMG,为我的疏忽道歉(已删除答案)。谢谢
【解决方案2】:

使用sed 的稍微简单的解决方案:

sed 's/$/|0/;1s/0/E/' a.csv; sed '1d;s/|/|0|/2' b.csv

【讨论】:

    【解决方案3】:

    为了便于阅读,我将我的答案扩展为脚本。您可以使用带有awk -f 选项的脚本。从BEGIN 语句开始:指定| 作为字段分隔符,使用关联数组将索引映射到每个标题标签并打印完整标题。对于每个文件,将标签映射到第 1 行的索引。然后将标签映射到第 2 行的数据,并将空数据字段替换为“0”。打印填写的行并清除下一个文件的数组。

    BEGIN{
        # field separator
        FS="|"
    
        # index:label mapping
        map[1]="date "; map[2]="A"; map[3]="B"
        map[4]="C"; map[5]="D"; map[6]="E"
    
        # print full header
        print "date |A|B|C|D|E"
    }
    
    # first line of each file, create index:label mapping
    FNR==1{
    
        for (i=1;i<=NF;i++)
            label[i]=$i
    }
    
    # next line of the file, create label:data mapping
    FNR==2{
        for (i=1;i<=NF;i++)
            data[label[i]]=$i
    
        # cycle through index:label mapping and print data
        # for each label or "0" if there is no data
        printf("%s", data["date "])
        for (i=2;i<=6;i++) {
            (data[map[i]]) ? s=data[map[i]] : s=0
            printf("|%s", s)
            }
        print ""  # print empty string for newline
    
        # delete arrays to start from scratch on the following file
        delete label  
        delete data
    }
    

    两个示例文件的结果:

    $ awk -f joiner.awk a.csv b.csv 
    date |A|B|C|D|E
    15-03-2017|1|3|9|4|0
    16-03-2017|2|0|9|3|4
    

    【讨论】:

      【解决方案4】:

      我解决了这个问题

      我改变了获取数据的方式

      类似这样的:

      today=$(date +%Y%m%d)
      echo "DataBase "$(date +%d/%m/%Y)>/jdb"$today".txt
      du -s $(ls -l|grep ^d|awk '{print $9})|awk '{print $2" "$1" "}'>>/jdb"$today".txt
      

      输出如下:

      jdb_20170507.txt:

      database 07/05/2017
      jdb_A 4345
      jdb_CFX 7654
      jdb_ZZXD 97865
      

      jdb_20170508.txt:

      database 08/05/2017
      jdb_A 9876
      jdb_CFX 7545
      jdb_ZXCFG  2344
      

      对于 jdb_20170508.txt 中的示例,删除了 jdb_ZZXD 数据库并创建了 jdb_ZXCFG 数据库

      有了这个结构,我可以使用 JOIN 命令:

      x=0
      touch jdbaux$x.txt
      for jdbfile in $(ls -1t|grep jdb2)
        do
          y=$(($x+1))
          join -a1 -a2 -e0 -o auto --nocheck-order jdbaux$x.txt $jdbfile >jdbaux$y.txt
          rm jdbaux$x.txt
          x=$(($x+1))
      done
      

      这是我本月所有档案的递归 JOIN 乡村选项

      -a1= 文件一

      -a2=文件二

      -e0=用 0 替换缺少的输入字段

      -o auto=输出自动格式

      --nocheck-order =不检查输入是否正确排序

      输出如下: jdb_sizes201705.txt:

      database 07/05/2017 08/05/2017
      jdb_A 4345 9876
      jdb_CFX 7654 7545
      jdb_ZZXD 97865 0
      jdb_ZXCFG 0 2344
      

      最后一步是枢轴

      cat jdb_sizes201705.txt |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
          }
      }'
      

      获得预期的输出

      database jdb_A jdb_CFX jdb_ZZXD jdb_ZXCFG
      07/05/2017 4345 7654 97865 0
      08/05/2017 9876 7545 0 2344
      

      我知道这不是最好的解决方案,但它确实有效!

      谢谢!

      【讨论】:

        猜你喜欢
        • 2012-06-24
        • 2016-05-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-07-15
        • 2021-10-04
        • 2020-05-13
        • 2019-10-22
        相关资源
        最近更新 更多