paste 命令详解与参数实测(Ubuntu 22.04)
GNU paste 参数实测:TAB 横并、-d 分隔符轮换、-s 串行、- 占位与 cat 纵向对照,Ubuntu 22.04(coreutils 8.32)全部命令回显实测。
paste 命令详解与参数实测(Ubuntu 22.04)
目标:全面掌握 GNU paste 的每一个参数——默认 TAB 横并、
-d自定义分隔符与多分隔符轮换、-s把多行串成一行、-占位符把 stdin 当输入列、cat 纵向与 paste 横向的对照,以及不等长文件的补空行为,全部命令与回显已在 Ubuntu 22.04(GNU coreutils 8.32)实测通过。
一、环境信息
- 操作系统:Ubuntu 22.04.5 LTS(x86_64)
- paste 版本:GNU coreutils 8.32(
paste --version实测) - paste 属于 coreutils 基础工具集,Ubuntu 22.04 默认预装,无需额外安装
- 演示目录:
/root/demo/paste/ - 测试数据:
names.txt(4 行姓名)、scores.txt(3 行分数,与姓名行数不等)、cities.txt(3 行城市)
二、命令概览
2.1 语法与测试数据准备
paste 的语法是 paste [OPTION]... [FILE]...:把每个 FILE 的第 N 行横向拼到同一行输出,列间默认用 TAB 分隔;无 FILE 或 FILE 为 - 时从标准输入读取。它是"按行号对齐"的横向合并——不管内容是什么,第 1 行对第 1 行、第 2 行对第 2 行。
准备三个列式小文件(姓名 4 行、分数 3 行、城市 3 行,故意不等长以观察补空行为):
mkdir -p /root/demo/paste
cat > /root/demo/paste/names.txt <<'EOF'
Alice
Bob
Carol
David
EOF
cat > /root/demo/paste/scores.txt <<'EOF'
90
85
78
EOF
cat > /root/demo/paste/cities.txt <<'EOF'
beijing
shanghai
guangzhou
EOF
进入演示目录并确认数据就绪:
$ cd /root/demo/paste
$ paste names.txt scores.txt cities.txt > /dev/null && ls -l names.txt scores.txt cities.txt
-rw-r--r-- 1 root root 27 Oct 15 07:35 cities.txt
-rw-r--r-- 1 root root 22 Oct 15 07:35 names.txt
-rw-r--r-- 1 root root 9 Oct 15 07:35 scores.txt
$ cat names.txt
Alice
Bob
Carol
David
names.txt 4 行、scores.txt 与 cities.txt 各 3 行,行数差在后续实测中会体现为补空列。
2.2 --help 全量回显
paste --help 输出全部参数清单(实测原样保留,可作为参数速查):
Usage: paste [OPTION]... [FILE]...
Write lines consisting of the sequentially corresponding lines from
each FILE, separated by TABs, to standard output.
With no FILE, or when FILE is -, read standard input.
Mandatory arguments to long options are mandatory for short options too.
-d, --delimiters=LIST reuse characters from LIST instead of TABs
-s, --serial paste one file at a time instead of in parallel
-z, --zero-terminated line delimiter is NUL, not newline
--help display this help and exit
--version output version information and exit
GNU coreutils online help: <https://www.gnu.org/software/coreutils/>
Report any translation bugs to <https://translationproject.org/team/>
Full documentation <https://www.gnu.org/software/coreutils/paste>
or available locally via: info '(coreutils) paste invocation'
💡 说明:paste 只有 3 个功能参数——
-d(分隔符,支持多字符轮换)、-s(串行模式)、-z(NUL 行界,配合-print0类链路用)。帮助原文点明两个关键语义:"sequentially corresponding lines"(按行序对应)与 "reuse characters from LIST"(分隔符列表循环复用)。
2.3 版本确认
$ paste --version | head -1
paste (GNU coreutils) 8.32
三、参数逐项实测
3.1 默认用法:两文件横并(TAB 分隔)
不带参数,两个文件按行并排,列间是 TAB:
$ paste names.txt scores.txt
Alice 90
Bob 85
Carol 78
David
$ paste names.txt scores.txt | cat -A
Alice^I90$
Bob^I85$
Carol^I78$
David^I$
cat -A 把 TAB 显示为 ^I:每行 姓名^I分数。注意第 4 行 David^I$——scores.txt 只有 3 行,paste 不报错而是补一个空字段,列结构保持完整(详见 3.6)。
💡 技术拓展:把多份数据"合到一起"有三个方向,选错工具效率天差地别——
工具 方向 对齐依据 适用 cat 纵向堆叠 不对齐,直接追加 追加日志、合并清单 paste(本文主角) 横向并列 按行号 行序天然对应的列拼接 join 横向关联 按键列值 数据库式按主键合并 本文实测的是行号对齐的 paste;若两份数据要靠"第 1 列的 ID"对上,应该用 join(见《join 命令详解与参数实测(Ubuntu 22.04)》)。
3.2 -d:自定义分隔符与多分隔符轮换
-d LIST 用 LIST 中的字符代替 TAB。单字符时每列用同一个分隔符:
$ paste -d , names.txt scores.txt
Alice,90
Bob,85
Carol,78
David,
$ paste -d , names.txt scores.txt | head -2
Alice,90
Bob,85
多字符时按列的位置循环取字符:三文件加 -d ',;',第 1、2 列之间用 ,,第 2、3 列之间用 ;:
$ paste -d ',;' names.txt scores.txt cities.txt
Alice,90;beijing
Bob,85;shanghai
Carol,78;guangzhou
David,;
最后一行 David,; 再次体现补空:两个空字段之间、之后的分隔符照样输出。其他字符(如竖线)同理:
$ paste -d '|' names.txt scores.txt
Alice|90
Bob|85
Carol|78
David|
💡 提示:LIST 里可用转义序列,
\t是 TAB、\n是换行、\0是空串(帮助原文:"reuse characters from LIST",转义细节见 man);-d只认单字符序列,想要多字符分隔符得靠sed后处理。
3.3 -s:把多行串成一行
-s(--serial)从"并行"切换为"串行":每个文件的所有行合并成一行,文件与文件之间换行:
$ paste -s -d , names.txt
Alice,Bob,Carol,David
$ paste -s -d , scores.txt
90,85,78
$ paste -s names.txt scores.txt
Alice Bob Carol David
90 85 78
$ paste -s names.txt scores.txt | cat -A
Alice^IBob^ICarol^IDavid$
90^I85^I78$
单文件加 -d , 得到逗号串(Alice,Bob,Carol,David);多文件加 -s 则每个文件各占一行、行内仍用默认 TAB(cat -A 可见 ^I)。这是"把列变行"的最短路径。
💡 提示:
paste -sd, 文件是临时拼 CSV 行、拼枚举列表的常用套路;配合管道还有求和妙用,见 4.3。
3.4 - 占位:stdin 当作输入文件
- 是输入占位符,一个 - 占一列,stdin 的内容从该列流入。奇偶行拆两列是最经典的应用:
$ printf 'odd1\nodd2\neven1\neven2\n' | paste - -
odd1 odd2
even1 even2
4 行输入被两两配对成 2 行 2 列——第 1、3 行进第一列,第 2、4 行进第二列。- 与文件还能混用,stdin 列可以放在任意位置:
$ paste - names.txt < scores.txt
90 Alice
85 Bob
78 Carol
David
stdin(scores.txt 内容)在第 1 列、names.txt 在第 2 列,实现了列序对调;最后一行第 1 列为空(分数只有 3 行)。
💡 提示:
paste - -对"隔行提取"类数据整理(偶数行跟奇数行配对)几乎是零成本方案,比 awk 脚本更直白。
3.5 cat 纵向拼接与 paste 横向拼接对照
同样两个文件,cat 是首尾相接,paste 是并排对齐,行数差异直观:
$ cat names.txt scores.txt
Alice
Bob
Carol
David
90
85
78
$ wc -l names.txt scores.txt
4 names.txt
3 scores.txt
7 total
$ paste names.txt scores.txt | wc -l
4
cat 拼出 7 行(4 + 3),paste 拼出 4 行(取最长文件的行数,短文件补空列)。一句话:cat 增加内容长度,paste 增加内容宽度。
3.6 不等长文件的行为
行数不齐时,短文件耗尽后以空字段补位,不报错、不截断长文件:
$ paste names.txt scores.txt
Alice 90
Bob 85
Carol 78
David
$ paste names.txt scores.txt | cat -A | head -4
Alice^I90$
Bob^I85$
Carol^I78$
David^I$
第 4 行 David^I$:姓名列有值,分数列是空的(TAB 后直接行尾)。空字段与 -d 组合时会连分隔符一起输出(3.2 的 David,;),解析端要按"空字段"处理而不是缺列。
💡 提示:paste 的补空策略是"行号对齐"的必然结果;如果业务上不允许错位合并,先确认两文件行数一致(
wc -l),或改用按键关联的 join。
四、实战示例
4.1 三列花名册:并排查看与一键 CSV
三个属性文件并排成花名册视图:
$ paste names.txt scores.txt cities.txt
Alice 90 beijing
Bob 85 shanghai
Carol 78 guangzhou
David
把分隔符换成逗号并重定向落盘,即得 CSV:
$ paste -d , names.txt scores.txt cities.txt > roster.csv
$ cat roster.csv
Alice,90,beijing
Bob,85,shanghai
Carol,78,guangzhou
David,,
David,, 行保留了完整的 3 列结构(姓名 + 两个空字段),下游 CSV 解析器可正确读取。注意 paste 不做 CSV 转义,字段本身含逗号/引号时需先清洗。
4.2 序号流两两配对
生成序列后用 - 占位配对,常用于造测试用例、构造键值对:
$ seq 1 6 | paste - -
1 2
3 4
5 6
$ seq 1 6 | paste -d : - -
1:2
3:4
5:6
paste -d : - - 一步产出 1:2 形式的键值行,可直接交给后续按 : 切分的处理。
4.3 管道求和:paste -sd+ 与 bc
把竖列数字串成加法算式再交给 bc 计算,是无临时文件的快速求和法:
$ command -v bc
/usr/bin/bc
$ seq 1 5 | paste -sd+ -
1+2+3+4+5
$ seq 1 5 | paste -sd+ - | bc
15
paste -sd+ - 把 5 行串成 1+2+3+4+5(- 表示读 stdin),bc 求值得 15。同样套路可换成 *(阶乘)等任意 bc 支持的运算符。
五、注意事项与常见问题
Q1:列之间的分隔符是什么?怎么确认?
默认 TAB。肉眼难分辨时用 cat -A 查看,TAB 显示为 ^I(3.1 实测);需要其他分隔符用 -d。
Q2:两个文件行数不一样会报错吗?
不会。以最长文件的行数为准,短文件耗尽后补空字段(3.6 实测 David^I$);这既是便利也是陷阱——错位的数据合并不会报错,合并前先用 wc -l 核对行数更稳。
Q3:-d 给多个字符时怎么分配?
按"列的位置"循环取用:-d ',;' 时第 1→2 列用 ,、第 2→3 列用 ;,列再多则从头循环(3.2 实测三文件输出 Alice,90;beijing)。
Q4:- 是什么含义?
输入占位符:一个 - 占一列,该列数据来自 stdin。paste - - 是奇偶配对、paste - 文件 可把 stdin 放到任意列(3.4 实测)。
Q5:能用 paste 生成标准 CSV 吗?
简单字段可以(-d ,,见 4.1);但 paste 不做引号转义,字段内含逗号、引号、换行时产出的不是合法 CSV,需先清洗字段或改用支持 CSV 的工具。
Q6:-s 之后行序是什么样的?
串行模式下每个文件压成一行,文件按参数顺序各占一行(3.3 实测两文件输出两行)。想压缩单个文件就是 paste -s -d 分隔符 文件。
Q7:paste 与 join 都能合并两个文件,用哪个? 行序天然一一对应用 paste(按行号对齐);两份数据要按键值(如 ID)匹配用 join——join 需要排序、支持内外连接,代价更高但能容忍行序差异,对比见《join 命令详解与参数实测(Ubuntu 22.04)》。
六、参考链接
- GNU coreutils 官方手册(paste 章节):https://www.gnu.org/software/coreutils/manual/html_node/paste-invocation.html
- 在线文档:https://www.gnu.org/software/coreutils/paste
- 本机帮助:
paste --help、man paste(Ubuntu 22.04 内置)