Linux 命令:join

概述

Linux 中的 join 命令,这个命令的核心作用是按"关键字段"将多个文件的行关联合并 (类似数据库的 JOIN 操作),区别于 paste 仅按行号无脑拼接,join 会匹配两个文件中关键字段相同的行,再横向合并,是处理结构化文本(如 CSV、日志、数据清单)的核心工具。

资料合集:https://pan.quark.cn/s/6fe3007c3e95https://pan.quark.cn/s/561de99256a5https://pan.quark.cn/s/985f55b13d94https://pan.quark.cn/s/d0fb20abd19a

一、核心前提(必看)

使用 join硬性要求

  1. 待合并的文件必须按关键字段排序(否则无法正确匹配);
  2. 默认以第一列作为关键字段(可通过选项指定其他列);
  3. 仅支持两个文件的合并(多文件需多次拼接);
  4. 字段默认用空格/制表符分隔(可自定义分隔符)。

二、基本语法

bash 复制代码
join [选项] 文件1 文件2
  • 无选项时,默认按第一列(关键字)合并,输出"关键字 + 文件1剩余列 + 文件2剩余列";
  • 支持 - 作为文件参数,代表读取标准输入。

三、常用选项(按功能分类)

join 的选项围绕"关键字段、分隔符、匹配规则"设计,覆盖数据库 JOIN 的核心逻辑:

选项分类 选项 作用 实用场景
关键字段配置
-1 N 指定文件1的第N列作为关键字 文件1关键字不在第一列时(如第3列是用户ID)
-2 N 指定文件2的第N列作为关键字 文件2关键字不在第一列时
分隔符配置
-t "字符" 指定字段分隔符(默认空格/制表符) 处理CSV文件(分隔符为逗号)、竖线分隔的文本
-o 格式 自定义输出列(如1.1 2.2代表文件1第1列+文件2第2列) 仅输出需要的列,避免冗余
匹配规则(核心)
-a 数字 显示指定文件的"不匹配行"(-a1=文件1所有行,-a2=文件2所有行) 实现 LEFT/RIGHT JOIN 效果
-v 数字 仅显示指定文件的"不匹配行"(-v1=仅文件1不匹配行) 找两个文件的差异行
-e "字符串" 用指定字符串填充空列(配合-a使用) 统一空值显示(如用"N/A"替代空)

四、基础示例(先理解核心逻辑)

先准备两个已排序的结构化文件(模拟用户信息和订单信息):

txt 复制代码
# file1.txt(用户信息:ID 姓名 年龄,关键字=ID)
1 张三 25
2 李四 30
3 王五 28
4 赵六 35

# file2.txt(订单信息:ID 订单号 金额,关键字=ID)
1 OD001 100
2 OD002 200
3 OD003 150
5 OD005 300
场景1:默认合并(INNER JOIN)

仅输出关键字(ID)在两个文件中都存在的行:

bash 复制代码
join file1.txt file2.txt

输出结果(关键字+file1剩余列+file2剩余列):

复制代码
1 张三 25 OD001 100
2 李四 30 OD002 200
3 王五 28 OD003 150
  • 赵六(ID4)、ID5 因仅在单个文件存在,被过滤(这就是数据库的 INNER JOIN)。
场景2:LEFT JOIN(显示文件1所有行)

-a1 保留文件1的所有行,无匹配时补空:

bash 复制代码
join -a1 file1.txt file2.txt

输出结果:

复制代码
1 张三 25 OD001 100
2 李四 30 OD002 200
3 王五 28 OD003 150
4 赵六 35
  • 赵六(ID4)无订单,订单列为空;ID5 仍不显示(仅保留文件1所有行)。
场景3:FULL JOIN(显示所有行)

组合 -a1 -a2 实现全连接,配合 -e "N/A" 填充空值:

bash 复制代码
join -a1 -a2 -e "N/A" file1.txt file2.txt

输出结果:

复制代码
1 张三 25 OD001 100
2 李四 30 OD002 200
3 王五 28 OD003 150
4 赵六 35 N/A N/A
5 N/A N/A OD005 300
场景4:仅显示不匹配行(找差异)

-v1 仅显示文件1独有的行,-v2 仅显示文件2独有的行:

bash 复制代码
# 仅文件1独有的行(赵六)
join -v1 file1.txt file2.txt
# 输出:4 赵六 35

# 仅文件2独有的行(ID5)
join -v2 file1.txt file2.txt
# 输出:5 OD005 300

五、进阶实操(处理CSV/自定义关键字)

场景1:处理CSV文件(逗号分隔)

准备CSV文件(需先排序):

txt 复制代码
# user.csv(ID,姓名,城市)
1,张三,北京
2,李四,上海
3,王五,广州

# order.csv(订单号,用户ID,金额)
OD001,1,100
OD002,2,200
OD003,3,150
OD005,5,300

步骤1:先按关键字排序(order.csv的关键字是第2列,需先排序):

bash 复制代码
# 对order.csv按第2列(用户ID)排序,保存为sorted_order.csv
sort -t "," -k 2 order.csv > sorted_order.csv

步骤2:指定分隔符+自定义关键字+自定义输出列:

bash 复制代码
# -t ",":分隔符为逗号
# -1 1:file1(user.csv)关键字是第1列
# -2 2:file2(sorted_order.csv)关键字是第2列
# -o 1.2,1.3,2.1,2.3:输出列=姓名、城市、订单号、金额
join -t "," -1 1 -2 2 -o 1.2,1.3,2.1,2.3 user.csv sorted_order.csv

输出结果(CSV格式):

复制代码
张三,北京,OD001,100
李四,上海,OD002,200
王五,广州,OD003,150
场景2:管道配合(实时处理命令输出)

将两个命令的输出按关键字合并(用 - 代表标准输入):

bash 复制代码
# 模拟生成已排序的用户ID+消费额,与file1.txt合并
echo -e "1 500\n2 800\n3 600" | join -1 1 -2 1 file1.txt -

输出结果:

复制代码
1 张三 25 500
2 李四 30 800
3 王五 28 600

六、关键注意事项

  1. 排序是前提 :文件未排序会导致匹配失败,排序时需和join用相同的分隔符(如CSV用sort -t "," -k N);
  2. 分隔符统一 :若文件中字段分隔符是多个空格/制表符混合,可先用tr -s ' '压缩为单个空格;
  3. 关键字唯一 :若关键字重复,join会按笛卡尔积合并(如文件1ID1有2行,文件2ID1有3行,会生成6行);
  4. 空值处理 :无匹配的列默认为空,用-e可自定义填充值(需配合-a使用才生效);
  5. 二进制文件:仅支持文本文件,不支持二进制文件(如压缩包、镜像)。

七、与paste/cat的核心区别(必分清)

命令 合并逻辑 核心前提 适用场景
join 关键字段匹配合并(数据库JOIN) 文件需按关键字排序 关联结构化数据(用户+订单、ID+信息)
paste 行号无脑列拼接 无前提 简单列合并(姓名+年龄+职业)
cat 顺序纵向行拼接 无前提 合并文件行(日志片段、文本片段)

总结

join结构化文本的关联合并工具 ,核心价值是按关键字匹配行,日常高频用法:

  1. 基础内连接:join 文件1 文件2
  2. 左/右连接:join -a1/-a2 -e "N/A" 文件1 文件2
  3. 找差异行:join -v1/-v2 文件1 文件2
  4. 处理CSV:join -t "," -1 N -2 M 文件1 文件2
  5. 自定义输出列:join -o 1.X,2.Y 文件1 文件2
相关推荐
HLC++10 小时前
Linux的进程间通信
android·linux·服务器
华清远见IT开放实验室11 小时前
实验室建设案例 | 石家庄科技信息职业学院嵌入式实验室——从底层硬件到系统应用,一所应用型高校的嵌入式人才培养这样落地
linux·arm开发·stm32·嵌入式硬件·高校·实验室建设
groundhappy13 小时前
idalib安装和codex ida-mcp配置
linux·开发语言·python
通信小小昕14 小时前
Ubuntu 26.04 中文输入法安装
linux·运维·ubuntu
张小姐的猫15 小时前
【Linux】网络编程 —— HTTP协议(上)
linux·运维·服务器·网络·http·单例模式·策略模式
栩栩云生16 小时前
AI 写代码犯的错,早被写进了错题集
linux·安全·ai编程
imc.1117 小时前
linux基础IO
linux·运维·服务器
BelongPanda19 小时前
Linux Nginx 纯手动 Let‘s Encrypt 泛域名证书配置教程
linux·nginx
酷可达拉斯19 小时前
Linux操作系统-shell编程(0)
linux·运维·服务器·python·云计算
2301_7779983419 小时前
Linux中断机制:操作系统如何高效运行
linux·运维·服务器