Linux 合并文件 awk 命令

标签 linux join awk merge

我有两个文件;文件 1:

ARS-BFGL-BAC-10975 0.9303 688423261 1 01/04/2015 0.9983763305
ARS-BFGL-BAC-11025 0.9092 688423261 1 01/04/2015 0.9983763305
ARS-BFGL-BAC-11044 0.9626 688423261 2 01/04/2015 0.9983763305
ARS-BFGL-BAC-11193 0.9544 688423261 1 01/04/2015 0.9983763305
ARS-BFGL-BAC-10975 0.9303 688423263 1 01/04/2015 0.9983763000
ARS-BFGL-BAC-11025 0.9082 688423263 1 01/04/2015 0.9983763000
ARS-BFGL-BAC-11044 0.9926 688423263 2 01/04/2015 0.9983763000
ARS-BFGL-BAC-11193 0.9144 688423263 1 01/04/2015 0.9983763000

第二个文件,文件2:

ARS-BFGL-BAC-10975 10 21225382
ARS-BFGL-BAC-11025 10 84516867
ARS-BFGL-BAC-11193 1 29303546

期望的输出:

ARS-BFGL-BAC-10975 0.9303 688423261 1 01/04/2015 0.9983763305 10 21225382
ARS-BFGL-BAC-11025 0.9092 688423261 1 01/04/2015 0.9983763305 10 84516867
ARS-BFGL-BAC-11193 0.9544 688423261 1 01/04/2015 0.9983763305 1 29303546
ARS-BFGL-BAC-10975 0.9303 688423263 1 01/04/2015 0.9983763000 10 21225382
ARS-BFGL-BAC-11025 0.9992 688423263 1 01/04/2015 0.9983763000 10 84516867
ARS-BFGL-BAC-11193 0.9144 688423263 1 01/04/2015 0.9983763000 1 29303546

所以文件 1 的行数比文件 2 多。我只想保留文件 2 中基于第一列的输出行,所以我想要 ARS-BFGL-BAC-10975 重复出现在文件 2 中的第 1 列中的次数,但我不希望 ARS-BFGL-BAC-11044 出现在输出中,因为它从未出现在文件 2 中.

我最接近的是以下 awk 命令,但它不允许 ARS-BFGL-BAC-10975 被复制,即我只在输出时合并到文件 2 的长度应该更长。

awk 'FNR==NR{a[$1]=$2 FS $3;next} $1 in a {print $0, a[$1]}' file2 file1 > output

最佳答案

这按预期工作

$ awk 'NR==FNR{a[$1]=$2 FS $3; next} $1 in a{print $0, a[$1]}' file2 file1

ARS-BFGL-BAC-10975 0.9303 688423261 1 01/04/2015 0.9983763305 10 21225382
ARS-BFGL-BAC-11025 0.9092 688423261 1 01/04/2015 0.9983763305 10 84516867
ARS-BFGL-BAC-11193 0.9544 688423261 1 01/04/2015 0.9983763305 1 29303546
ARS-BFGL-BAC-10975 0.9303 688423263 1 01/04/2015 0.9983763000 10 21225382
ARS-BFGL-BAC-11025 0.9082 688423263 1 01/04/2015 0.9983763000 10 84516867
ARS-BFGL-BAC-11193 0.9144 688423263 1 01/04/2015 0.9983763000 1 29303546

没有限制有多少 file1 记录将匹配到 file2,但显然 file2 键应该是唯一的。当您运行相同的脚本时,我不确定您得到了什么。

如果您不介意丢失顺序,您可以使用joinsorted 文件

$ join <(sort file1) <(sort file2)

ARS-BFGL-BAC-10975 0.9303 688423261 1 01/04/2015 0.9983763305 10 21225382
ARS-BFGL-BAC-10975 0.9303 688423263 1 01/04/2015 0.9983763000 10 21225382
ARS-BFGL-BAC-11025 0.9082 688423263 1 01/04/2015 0.9983763000 10 84516867
ARS-BFGL-BAC-11025 0.9092 688423261 1 01/04/2015 0.9983763305 10 84516867
ARS-BFGL-BAC-11193 0.9144 688423263 1 01/04/2015 0.9983763000 1 29303546
ARS-BFGL-BAC-11193 0.9544 688423261 1 01/04/2015 0.9983763305 1 29303546

只需一点点额外的杂耍,您就可以恢复秩序(装饰/取消装饰)

$ join -12 <(cat -n file1 | sort -k2) <(sort file2) | 
  sort -k2,2 | cut -d' ' -f2 --complement

ARS-BFGL-BAC-10975 0.9303 688423261 1 01/04/2015 0.9983763305 10 21225382
ARS-BFGL-BAC-11025 0.9092 688423261 1 01/04/2015 0.9983763305 10 84516867
ARS-BFGL-BAC-11193 0.9544 688423261 1 01/04/2015 0.9983763305 1 29303546
ARS-BFGL-BAC-10975 0.9303 688423263 1 01/04/2015 0.9983763000 10 21225382
ARS-BFGL-BAC-11025 0.9082 688423263 1 01/04/2015 0.9983763000 10 84516867
ARS-BFGL-BAC-11193 0.9144 688423263 1 01/04/2015 0.9983763000 1 29303546

关于Linux 合并文件 awk 命令,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35977680/

相关文章:

bash - 在 awk 脚本的 BEGIN 部​​分中确定 NR

linux - 使用打印两个不同的文件字段

linux - Fedora 上未安装 Vim

两个 SELECT 语句之间的 MySQL 笛卡尔积

SQL:如何获取表的每个最大值?

MySQL JOIN 使用 IF 条件对非唯一值进行连接

awk - 从使用 sed 获得的部分中获取上面的 N 行

linux - 管道 'tail -f' 到 awk 没有挂起

linux - 在本地机器上通过 ssh 创建和更新存档

linux - Tar 将相对符号链接(symbolic link)更改为绝对符号链接(symbolic link)