首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >bash?-把文件合并到CSV中

bash?-把文件合并到CSV中
EN

Stack Overflow用户
提问于 2016-11-02 05:41:13
回答 3查看 72关注 0票数 0

我知道(请参阅here),如果每个文件包含一个列,则可以使用paste将多个文件组合成一个.csv文件。

也就是说..。paste -d "," column1.dat column2.dat column3.dat ... > myDat.csv将导致

myDat.csv

代码语言:javascript
复制
column1,   column2,   column3, ...
c1-1,      c2-1,      c3-1,    ...
c1-2,      c2-2,      c3-2,    ...
...        ...        ...

(没有标签。只需插入它们,使其更易读)

如果我有多个测量值呢?

例如:

file1.dat格式为<xvalue> <y1value>

file2.dat格式为<xvalue> <y2avlue>

file3.dat格式为<xvalue> <uvalue> <vvalue>

我最终想要一个csv

代码语言:javascript
复制
<xvalue>, <y1value>, <y2value>, <empty column>, <uvalue>, <vvalue>

我现在该如何组合这些文件?

编辑

注意,虽然每个文件都是排序的(或者如果没有排序的话也可以排序),但它们不一定包含相同行上相同的xvalue。

如果一个文件没有另一个文件所具有的xvalue,那么它相应的列条目应该是空的。

(实际上,我认为删除不存在于所有文件中的xvalue行也应该有效。)

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2016-11-03 18:25:43

好的,下面是我在Gnu awk中的解决方案,它试图成为一个更通用的解决方案,并使用外部工具处理额外的空列。它在Gnu awk中,因为它使用多维数组,但也可能很容易地推广到其他awk。

该程序连接期望每个文件的第一个字段为键列的字段。如果找不到要连接的键,则会创建一个新键,并在输出时将不存在的字段输出为空(注意数据文件中下面的键x_3x_4x_5 )。

首先是数据文件:

代码语言:javascript
复制
$ cat file[123].dat             # 3 files, separated by empty lines for clarity
x_1 y1_1
x_2 y1_2
x_3 y1_3

x_1 y2_1
x_2 y2_2
x_4 y2_4

x_1 u_1 v_1
x_2 u_2 v_2
x_5 u_5 v_5

守则如下:

代码语言:javascript
复制
$ cat program.awk
BEGIN { OFS=", " }
FNR==1 { f++ }                                # counter of files
{
    a[0][$1]=$1                               # reset the key for every record 
    for(i=2;i<=NF;i++)                        # for each non-key element
        a[f][$1]=a[f][$1] $i ( i==NF?"":OFS ) # combine them to array element
}
END {                                         # in the end
    for(i in a[0])                            # go thru every key
        for(j=0;j<=f;j++)                     # and all related array elements
            printf "%s%s", a[j][i], (j==f?ORS:OFS)
}                                             # output them, nonexistent will output empty

使用和产出:

代码语言:javascript
复制
$ awk -f program.awk \
file1.dat \
file2.dat \
<(grep -h . file[123].dat|cut -d\  -f 1|sort|uniq) \
file3.dat 
x_1, y1_1, y2_1, , u_1, v_1
x_2, y1_2, y2_2, , u_2, v_2
x_3, y1_3, , , 
x_4, , y2_4, , 
x_5, , , , u_5, v_5

file2.dat之后的空列将通过收集所有键并输入为另一个“文件”(使用进程替换<())来创建空字段来生成,以使程序更通用:

代码语言:javascript
复制
$ grep -h . file[123].dat|cut -d\  -f 1|sort|uniq
x_1
x_2
x_3
x_4
x_5
票数 1
EN

Stack Overflow用户

发布于 2016-11-02 05:46:35

就用一个进程替代?

代码语言:javascript
复制
paste -d, > myDat.csv \
  file1.dat \
  <(cut -d' ' -f2 file2.dat) \
  /dev/null \
  <(cut -d' ' -f2,3 file3.dat)
票数 1
EN

Stack Overflow用户

发布于 2016-11-02 05:59:44

可以使用paste组合所有文件,然后使用awk只打印所需的列(包括空列):

代码语言:javascript
复制
paste file1.dat file2.dat file3.dat | awk -v OFS=', ' '{print $1,$2,$4,"",$6,$7}'

注意,$3$5列被排除在awk命令之外,因为它们与列$1相同(即它们都是<xvalue>)。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/40373180

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档