多行合并成一行是什么场景
把每行一项的清单合并成一行,是文档搬运、配置生成、命令行参数构造里的高频需求:比如把 IP 列表变成逗号分隔的字符串喂给接口,把主机名拼成批量执行命令的参数,或者把编号清单拼成 SQL 的 IN 列表。coreutils 里 paste -sd 是最直接的做法,tr 把换行替换成分隔符更快但末尾会多一个分隔符,awk 能精确控制分隔符并支持每 N 行分组。选哪个取决于是否需要去掉末尾分隔符、是否需要分组。
基本信息
| 适用平台 | GNU/Linux、macOS(paste、tr、awk 均为标准工具) |
|---|---|
| 核心目标 | 把多行清单合成单个分隔字符串 |
| 候选工具 | paste -sd、tr、awk、sed -z、xargs -n |
| 关键差异 | paste -sd 末尾不补分隔符,tr 会多出一个 |
| 分组拼接 | xargs -n5 或 awk 用行号取模 |
| 长度限制 | 命令行参数总量受 ARG_MAX 限制 |
典型使用场景
- 把 IP 或域名清单拼成接口要求的逗号分隔字符串。
- 生成重复的 curl 参数或白名单配置,避免手写一长串。
- 把主机列表拼成一条批量执行命令的参数串。
- 按每 5 行一组拼接,生成分批处理的输入块。
- 拼出 SQL 的 IN 列表或查询条件串。
常用写法
常用写法
paste -sd, hosts.txt # 输出 a,b,c,末尾不加逗号
tr '\n' ',' < hosts.txt | sed 's/,$/\n/' # tr 会补末尾逗号,用 sed 清理
awk 'NR>1{printf ","} {printf "%s",$0} END{print ""}' hosts.txt # 精确控制分隔符
awk '{printf "%s%s", $0, (NR%5==0?"\n":",")}' list.txt # 每 5 行一组
xargs -n5 < hosts.txt | sed 's/ /,/g' # 另一种分组写法
sed -z 's/\n/,/g; s/,$/\n/' hosts.txt # 一次替换,大文件更省内存
paste -sd, <(sort -u hosts.txt) # 先去重再合并
paste -sd' ' hosts.txt # 空格分隔,用于拼参数写法与输出对照
| 写法 | 典型输出 | 使用要点 |
|---|---|---|
| paste -sd, | a,b,c | 末尾不补分隔符,最省事 |
| tr 换行替换 | a,b,c, | 末尾多一个分隔符,必须清理 |
| awk 拼接 | 完全可控 | 适合需要条件分隔或按行分组的场景 |
| xargs -n5 | 每行 5 项 | 默认按空白拆词,含空格的值会散 |
| sed -z | 一次替换完成 | GNU 专有,处理大文件内存更友好 |
末尾分隔符是最常见的差异点:paste -sd 不补、tr 会补。下游对空字段敏感时(SQL 的 IN 列表、逗号分隔的接口参数)必须清理干净,否则会解析出一个空元素。
命令行长度有 ARG_MAX 上限(Linux 上总量通常 2MB 左右,单个参数还另有更小的限制):几万行的清单不要塞进变量或作为参数传递,直接从管道喂给下游程序。
xargs -n 是最短的分组路径,但它默认按空白拆词:清单里含空格的值会被打散,需要先用 -d 指定换行作为分隔符,或改用 awk 方案。