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