linux - AWK 比较两个单独文件中的两列

标签 linux bash awk comparison data-analysis

我想比较两个文件并执行如下操作:如果第一个文件中的第 5 列等于第二个文件中的第 5 列,我想打印第一个文件中的整行。那可能吗?我搜索了这个问题,但找不到解决方案:(

文件由制表符分隔,我尝试过这样的操作:

zcat file1.txt.gz file2.txt.gz | awk -F'\t' 'NR==FNR{a[$5];next}$5 in a {print $0}'

有没有人试过做类似的事情? :)

在此先感谢您的帮助!

最佳答案

您的脚本没问题,但您需要将每个文件单独提供给 awk 并以相反的顺序提供。

$ cat file1.txt
a b c d 100
x y z w 200
p q r s 300
1 2 3 4 400

$ cat file2.txt
. . . . 200
. . . . 400

$ awk 'NR==FNR{a[$5];next} $5 in a {print $0}' file2.txt file1.txt
x y z w 200
1 2 3 4 400

编辑:

正如评论中所指出的,上面的通用解决方案可以改进并适应 OP 从压缩的制表符分隔文件开始的情况:

$ awk -F'\t' 'NR==FNR{a[$5];next} $5 in a' <(zcat file2.txt) <(zcat file1.txt)
x y z w 200
1 2 3 4 400

解释:

NR是当前正在处理的记录的编号,FNR是编号 当前记录在其文件中。因此 NR == FNR 只是 当 awk 正在处理给它的第一个文件(在我们的例子中是 file2.txt)时为真。

a[$5] 将第 5 列的值作为索引添加到数组 a 中。 awk 中的数组是关联数组,但通常您并不关心关联一个值,而只想制作一个漂亮的东西集合。这是一个 收集我们在第 5 列中看到的所有值的简洁方法 第一个文件。接下来的 next 语句表示立即获取下一个 可用记录,而无需查看 awk 程序中的任何语句。

总结以上内容,这一行表示“如果您正在读取第一个文件 (file2.txt), 将第 5 列的值保存在名为 a 的数组中,然后继续记录没有 继续 awk 程序的其余部分。”

NR == FNR { a[$5]; next }

希望上面的内容很清楚,我们可以通过第一行的唯一方法 awk 程序是如果我们正在读取第二个文件(在我们的例子中是 file1.txt)。

$5 in a 如果第 5 列的值作为索引出现在 a 中,则计算结果为 true a 数组。换句话说,file1.txt 中第 5 个记录的每条记录都为真 我们在 file2.txt 的第 5 列中看到的列。

在 awk 中,当模式部分计算为真时,伴随的 Action 是 调用。当没有给出 Action 时,如下所示,触发默认 Action 相反,这是简单地打印当前记录。因此,只要说 $5 in a,我们告诉 awk 打印 file1.txt 中的所有记录,其第 5 个 列也出现在 file2.txt 中,这当然是给定的要求。

$5 in a

关于linux - AWK 比较两个单独文件中的两列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34420217/

相关文章:

mysql - 使用脚本将 .csv 文件加载到 MySQL 数据库中

bash - 如何编写 Unix 脚本以在多个远程服务器上快速启动服务?

linux - FORTRAN 内存利用率 - 静态与动态

AWK:如何将列中的值减一

awk - 如何用 CLI 上某些行的逗号替换\n

linux - shell Bash 脚本

php - 使用 php/curl、linux 的 HTML5 横幅屏幕截图

c++ - mysql和c++连接

linux - 使用 Bash 按名称杀死进程?

awk - 提取所有列值大于或等于阈值的行