在 bash 中根据列(即标题)合并制表符分隔的 txt 文件?

在 bash 中根据列(即标题)合并制表符分隔的 txt 文件?

我有两个包含百万条记录的文本文件,所有记录都以制表符分隔,我们如何根据相同的标题(列)合并这两个文件?

文件:1

    LogEntryTime              nameId       PartnerId        
    2021-06-05T15:00:53 07    5lsddf        qyutxwr 
        
        

文件:2

        nameId  GroupId  compnayId
        5lsddf  l4buafm   0rd33cs               
    

输出如下:

    LogEntryTime              nameId       PartnerId    GroupId  compnayId
    2021-06-05T15:00:53 07    5lsddf        qyutxwr     l4buafm   0rd33cs

尝试过这个但是没有用:

paste file1.txt file2.txt | nameId -s $'\t' -t

cat file1.txt file2.txt |  awk -F '\t' '{print $ list the all columns name here}'

awk 可以工作但需要在那里提及所有的列号。

还有其他解决方案可以帮助我吗?

提前致谢

答案1

nameId将其中一个文件循环到数组中,并用与公共字段相关的数组索引替换第二个文件的第一个字段(即)。

awk -F \\t+ -vOFS=\\t 'NR==FNR{a[$2]=$0;next} {$1=a[$1]}1' file{1,2}.txt

答案2

如果您的文件是正确构造的制表符分隔 (TSV) 文件,那么您可以使用csvjoin基于 Python 的csvkit包。

例如:

$ head file1.tsv file2.tsv | cat -A
==> file1.tsv <==$
LogEntryTime^InameId^IPartnerId$
2021-06-05T15:00:53 07^I5lsddf^Iqyutxwr$
$
==> file2.tsv <==$
nameId^IGroupId^IcompnayId$
5lsddf^Il4buafm^I0rd33cs$

cat -A使标签可见,如^I)然后

$ csvjoin -I -t -c nameId file1.tsv file2.tsv
LogEntryTime,nameId,PartnerId,GroupId,compnayId
2021-06-05T15:00:53 07,5lsddf,qyutxwr,l4buafm,0rd33cs

要以 TSV 格式恢复输出,请使用csvformat同一个包:

$ csvjoin -I -t -c nameId file1.tsv file2.tsv | csvformat -T
LogEntryTime    nameId  PartnerId       GroupId compnayId
2021-06-05T15:00:53 07  5lsddf  qyutxwr l4buafm 0rd33cs

请注意,-I禁用类型推断 - 有时可能会出现意外行为,尤其是在日期时间字段中。


更简单,使用磨坊主(可从 Universe 存储库以包形式获得miller):

$ mlr --tsv join -f file1.tsv -j nameId then reorder -f LogEntryTime file2.tsv
LogEntryTime    nameId  PartnerId       GroupId compnayId
2021-06-05T15:00:53 07  5lsddf  qyutxwr l4buafm 0rd33cs

reorder必需的,因为默认情况下mlr join会先输出公共字段(就像系统join命令一样)。请注意,对于未分类的输入,整个 都file1.tsv将加载到内存中。

答案3

利用这组特定的数据:

awk '
    BEGIN {FS = OFS = "\t"}
    NR == FNR {f1[$2] = $0; next}
    {$1 = f1[$1]; print}
' file{1,2}.txt

仅提到连接字段(文件 1 中的 $2,文件 2 中的 $1)。

产生制表符分隔的输出

LogEntryTime    nameId  PartnerId   GroupId compnayId
2021-06-05T15:00:53 07  5lsddf  qyutxwr l4buafm 0rd33cs

为了获得漂亮的输出,通过管道输入| column -t -s $'\t'以获取

LogEntryTime            nameId  PartnerId  GroupId  compnayId
2021-06-05T15:00:53 07  5lsddf  qyutxwr    l4buafm  0rd33cs

相关内容