【问题标题】:How to merge multiple .csv files using the 1st column of one of them as a index (shell scripting)如何使用其中一个的第一列作为索引来合并多个 .csv 文件(shell 脚本)
【发布时间】:2017-06-08 19:29:25
【问题描述】:

如何使用其中一个的第一列作为索引来合并多个 .csv 文件(pref shell scripting - awk)

88 个 .csv 文件看起来像这样 输入文件名 ZBND19X.csv

==> ZBND19X.csv <==
Gene,ZBND19X(26027342 pairs)
ENSTGUG00000013338 (GAPDH),984.31862471
ENSTGUG00000000915,862.597795025
ENSTGUG00000006651 (ARPP19),845.045872644
ENSTGUG00000005054 (CAMKV),823.404021741
ENSTGUG00000005949 (FTH1),585.628487964

和 ZBND22V.csv

==> ZBND39X.csv <==
Gene,ZBND39X(26558640 pairs)
ENSTGUG00000013338 (GAPDH),971.678203888
ENSTGUG00000005054 (CAMKV),687.81249397
ENSTGUG00000006651 (ARPP19),634.296191033
ENSTGUG00000002582 (ITM2A),613.756010638
ENSTGUG00000000915,588.002298061

输出文件名 RPKM_all.csv

Gene,ZBND19X(26027342 pairs),ZBND39X(26558640 pairs)
ENSTGUG00000013338 (GAPDH),984.31862471,971.678203888
ENSTGUG00000000915,862.597795025,588.002298061
ENSTGUG00000006651 (ARPP19),845.045872644,634.296191033
ENSTGUG00000005054 (CAMKV),823.404021741,687.81249397
ENSTGUG00000005949 (FTH1),585.628487964,0
ENSTGUG00000002582 (ITM2A),613.756010638,0

没有找到对应值时加0。

【问题讨论】:

  • 这些文件有多大?你是成对加入它们产生 44 个文件,还是全部加入一个 1 个文件?
  • 嘿!我想将所有 88 个文件合并为 1 个文件。所以输出将是:Gene,ZBND19X(26027342 对),ZBND39X(26558640 对), ... 88 谢谢。
  • 典型尺寸怎么样?
  • 文件大约 289K。

标签: shell csv awk


【解决方案1】:

join一次只能处理两个文件,来了

awk 来救援!

$ awk -F, 'FNR==1 {c++; h=h sep $2; sep=FS; next} 
                  {ks[$1]; a[$1,c]=$2} 
           END    {print h; 
                   for(k in ks) 
                     {printf "%s", k;
                      for(i=1;i<=c;i++) printf "%s", FS a[k,i]+0; 
                      print ""}}' files

免责声明:只有当数据可以放入内存时,订单才会丢失,但如果重要,有办法处理它。

解释概念上创建一个表(又名二维数组,矩阵)并填充条目。行按键索引,列按文件编号索引。由于awk 数组正在对键进行散列处理,因此我们分别对待标头以保持原位。 a[k,i]+0 是将缺失的元素转换为0

【讨论】:

  • 嘿!那行得通!你介意带我走过吗。我发现 awk 真的很神秘,但我对用它做一些事情越来越感兴趣。
【解决方案2】:

简单的答案是“加入”。

只要文件已排序,您就可以使用 join 命令匹配第一列(默认情况下)。

不要忘记对文件进行排序。

我有没有提到您需要对文件进行排序;)?这是一个容易犯的错误(我犯了很多错误;因此强调)。

sort  ZBND19X.csv >  ZBND19X.csv.sorted
sort ZBND39X.csv  > ZBND39X.csv.sorted
join -t, ZBND19X.csv.sorted ZBND39X.csv.sorted > RPKM_all.csv

这是上面运行后 RPKM_all.csv 的内容:

ENSTGUG00000000915,862.597795025,588.002298061
ENSTGUG00000005054 (CAMKV),823.404021741,687.81249397
ENSTGUG00000006651 (ARPP19),845.045872644,634.296191033
ENSTGUG00000013338 (GAPDH),984.31862471,971.678203888
Gene,ZBND19X(26027342 pairs),ZBND39X(26558640 pairs)

我们也可以像这样查找不匹配的行:

$ join -v1 -t, ZBND19X.csv.sorted ZBND39X.csv.sorted | awk -F, -v OFS=, '{print $1,$2,0}'
ENSTGUG00000005949 (FTH1),585.628487964,0

$ join -v2 -t, ZBND19X.csv.sorted ZBND39X.csv.sorted | awk -F, -v OFS=, '{print $1,0,$2}'
ENSTGUG00000002582 (ITM2A),0,613.756010638

现在你可以组合整个东西了:

sort  ZBND19X.csv >  ZBND19X.csv.sorted
sort ZBND39X.csv  > ZBND39X.csv.sorted
join -t, ZBND19X.csv.sorted ZBND39X.csv.sorted > RPKM_all.csv
join -v1 -t, ZBND19X.csv.sorted ZBND39X.csv.sorted | awk -F, -v OFS=, '{print $1,$2,0}' >> RPKM_all.csv
join -v2 -t, ZBND19X.csv.sorted ZBND39X.csv.sorted | awk -F, -v OFS=, '{print $1,0,$2}'  >> RPKM_all.csv

【讨论】:

  • 酷!但是,我怎么能对目录中的文件执行此操作?
【解决方案3】:

awk 代码(awk -F, 'FNR==1 {c++; h=h sep $2; sep=FS; next} ): 有没有人可以对此做更多解释,代码没有正确打印标题,所有标题只是跳转到不同的行并且第一个标题也丢失了

P21 P22 P24 P24

AamoA_EU022762 1 1 0 0 AamoA_EU099963 0 1 0 0

【讨论】:

  • 如果您有新问题,请点击 按钮提出问题。如果有助于提供上下文,请包含指向此问题的链接。 - From Review
猜你喜欢
  • 2019-02-10
  • 1970-01-01
  • 1970-01-01
  • 2013-03-13
  • 1970-01-01
  • 1970-01-01
  • 2014-05-17
  • 1970-01-01
  • 2012-02-14
相关资源
最近更新 更多