首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >合并多个txt文件

合并多个txt文件
EN

Unix & Linux用户
提问于 2019-12-04 20:45:20
回答 3查看 582关注 0票数 0

我有多个txt文件,其中3个就像:

file1:

代码语言:javascript
运行
复制
sample  input filtered
5809378   1      2
5811151   3      4
5811237   5      6

file2:

代码语言:javascript
运行
复制
sample  chi tri
5809378  7   8
5811151      
5811237  9   10

file3:

代码语言:javascript
运行
复制
sample   bra  doe
5809378  11 
5811151        12
5811237  13    14

我希望根据第一列:示例ID将这3个文件合并为1,因此输出如下:

代码语言:javascript
运行
复制
sample  input  filters  chi  tri   bra   doe
5809378    1     2      7     8     11     0
5811151    3     4      0     0     0     12
5811237    5     6      9     10    13    14

注意,如果没有相应的数据,则必须有一个零,或者在最坏的情况下,是一个空选项卡。

我试了一下awk并加入了,但找不到最好的解决方案。有人知道吗?

EN

回答 3

Unix & Linux用户

发布于 2019-12-04 22:21:13

在我看来,file3并不完全正确,因为行

5811151 12

第二列或第三列中可能有"12“号,这取决于我们读取文件的方式(没有定义列分隔符,而且在任何地方都不相同)。

不管怎么说。

代码语言:javascript
运行
复制
a=$(cat file1|awk '{if($2==""){$2="0"};if($3==""){$3="0"}; print $1,$2,$3}'|sort);
for f in file2 file3; do
    b=$(cat $f|awk '{if($2==""){$2="0"};if($3==""){$3="0"}; print $1,$2,$3}'|sort);
    a=$(join -j 1 <(echo "${a}") <(echo "${b}"));
done;
echo "${a}"|sort -n

输出是

代码语言:javascript
运行
复制
sample input filtered chi tri bra doe
5809378 1 2 7 8 11 0
5811151 3 4 0 0 12 0
5811237 5 6 9 10 13 14

所以,我们

1)转换为的每个文件

cat file|awk '{if($2==""){$2="0"};if($3==""){$3="0"}; print $1,$2,$3}'|sort

将缺失的数字替换为“0”和排序行。

( 2)在一个循环中,我们接受一个下一个文件并将其合并到以前的结果

join -j 1 file_current file_next

因此,行"for f in file2 file3;do“可以更改为包含更多文件,例如"for f in file2 file3 file4 file5 file6;do”。

( 3)打印结果,按照字符串数值排序(先排序,然后打印列名)。此外,如果需要,我们可以在这里格式化输出。

票数 0
EN

Unix & Linux用户

发布于 2019-12-05 02:39:51

假设您的文件有选项卡分隔的列(这样您就可以判断哪些列是空的,比如您的file3的第三行),并且像示例一样在第一列上排序,这样的bash脚本如下:

代码语言:javascript
运行
复制
#!/bin/bash

function fixup() { # Add 0's to blank columns
    awk -v cols="$2" 'BEGIN { FS = OFS = "\t" }
                      { for (i = 1; i <= cols; i++)
                         if ($i == "") $i = 0
                      } 1' "$1"
}

join --header -t将这样做:$ ./combine file1 file2 file3
sample  input   filtered        chi     tri     bra     doe
5809378 1       2       7       8       11      0
5811151 3       4       0       0       0       12
5811237 5       6       9       10      13      14(确实需要join的GNU核心功能版本)。\t' -j1 \
     <(join --header -t将这样做:A2(确实需要D3的GNU核心功能版本)。\t' -j1 <(fixup "$1" 3) \
                                 <(fixup "$2" 3)) \
     <(fixup "$3" 3)

将这样做:

A2

(确实需要D3的GNU核心功能版本)。

票数 0
EN

Unix & Linux用户

发布于 2019-12-05 18:48:54

另一种方法,假设有一个tab分隔符

首先,通过在双0 S之间插入一个tab,或者在没有文本(即标题)或数字[^[:alnum:]]的情况下,一行以$结尾来修复这些文件

代码语言:javascript
运行
复制
TAB=那就join他们join --header file2 file3 | join --header file1 - | column -t输出sample   input  filtered  chi  tri  bra  doe
5809378  1      2         7    8    11   0
5811151  3      4         0    0    0    12
5811237  5      6         9    10   13   14\t'; sed -Ei "s/([^[:alnum:]]|${TAB})($|${TAB})/\10\2/g" file*

那就D6他们

A7

输出

A8

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

https://unix.stackexchange.com/questions/555650

复制
相关文章

相似问题

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