paste 命令详解与参数实测(Ubuntu 22.04)

GNU paste 参数实测:TAB 横并、-d 分隔符轮换、-s 串行、- 占位与 cat 纵向对照,Ubuntu 22.04(coreutils 8.32)全部命令回显实测。

Linux命令Linux系统UbuntuUbuntu 22.04命令行文本处理2026/10/15

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)》。

六、参考链接