join 和 split 命令解决的是不同的文件处理问题。join 合并两个已排序文本输入中的相关记录,而 split 把一个输入划分成一系列较小的文件。
文本操作 · 第 11 课
join 和 split
学习如何按键连接两个已排序的文本文件,以及如何把一个文件拆分成命名片段。
按第一字段连接两个文件
默认情况下,join 会比较恰好两个输入文件中以空白分隔的第一个字段。假设有以下两个已经排序的文件。
people.txt:
1 John
2 Jane
3 Mary
surnames.txt:
1 Doe
2 Doe
3 Sue
连接键字段相等的记录:
$ join people.txt surnames.txt
1 John Doe
2 Jane Doe
3 Mary Sue
输出先包含一次共享键,然后依次是第一个和第二个文件中的其余字段。join 一次处理两个文件;它不接受三个普通文件操作数来执行三路关系连接。
不指定字段选项时,join first.txt second.txt 会合并哪些记录?
对连接键排序
每个输入都必须按照各自的连接字段排序,并使用兼容的比较规则。对于默认的第 1 字段,可使用 sort -k 1,1 准备副本:
$ LC_ALL=C sort -k 1,1 people-raw.txt > people.txt
$ LC_ALL=C sort -k 1,1 surnames-raw.txt > surnames.txt
$ LC_ALL=C join people.txt surnames.txt
排序和连接使用同一 locale,可以让排序规则保持一致。不要把排序结果重定向回原输入路径,因为 shell 会先截断该文件。
为了可靠匹配,join 通常要求进行什么准备?
选择不同的连接字段
使用 -1 FIELD 指定第一个文件的键,使用 -2 FIELD 指定第二个文件的键。假设第一个输入包含:
John 1
Jane 2
Mary 3
第二个输入包含:
1 Doe
2 Doe
3 Sue
先按字段 2 对第一个文件排序,按字段 1 对第二个文件排序,然后运行:
$ join -1 2 -2 1 people.txt surnames.txt
1 John Doe
2 Jane Doe
3 Mary Sue
如果字段由 : 之类的单个非空白字符分隔,请使用 -t CHARACTER。-a 1 或 -a 2 等选项可以包含某个输入中未配对的行;默认输出只包含匹配的键。
哪些选项会把第一个文件的字段 2 与第二个文件的字段 1 连接起来?
按行数拆分
split 会把一个输入中连续的片段写入不同的输出文件。它不是按键执行的 join 操作的逆过程。
$ split large.txt
GNU 的默认行为是每个输出文件最多写入 1000 行,并使用前缀 x,生成 xaa、xab 和 xac 等名称。
使用 -l NUMBER 选择行数,并添加最后一个操作数来选择输出前缀:
$ split -l 500 large.txt part-
这会生成 part-aa、part-ab 等文件,每个片段最多包含 500 行。
哪个命令会把 large.txt 拆成最多 500 行一份、名称以 part- 为前缀的片段?
按大小拆分
使用 -b SIZE 可按字节大小划分输入。在这里,GNU 的 K、M 和 G 等后缀表示 1024 的幂:
$ split -b 10M archive.bin chunk-
这会请求大小为 10 MiB 的片段,最后一片可能更小。split 不会创建归档清单或重组元数据;需要重建时,请保留后缀顺序,并按顺序拼接各片段。
哪个命令会把 archive.bin 拆成 10 MiB 一份、使用 chunk- 前缀的片段?
要练习按键连接和结构化数据处理,可以尝试以下动手实验:
- Linux join 命令:文件连接 - 这个实验直接介绍
join命令,让你练习根据共同字段合并两个已排序文本文件中的行,正如本课所讲。 - 处理员工数据 - 运用
join以及awk等其他强大的 Linux 命令行工具,组合并处理来自多个来源的数据,模拟真实的数据分析场景。
课程已完成
你已完成 join 和 split
现在,你可以合并已排序的记录,也可以把一个输入拆分成有序片段。
按相等的键字段连接恰好两个文件。
按连接键以一致方式排序两个输入。
使用
-1和-2选择非默认键字段。使用
-l按行数拆分。使用
-b和清晰的前缀按字节大小拆分。