You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在GNU sed中模拟BSD sed的输出换行行为?

在GNU sed中模拟BSD sed的自动追加换行行为

当然可以!问题的核心是BSD sed会强制给所有输出行追加换行符,哪怕输入行本身没有结尾的换行;而GNU sed默认会严格保留输入的换行状态。针对你处理nvidia-smi输出的场景,有几种简单可靠的方法能让GNU sed输出和BSD sed一致的结果:

方法1:在替换结果中显式添加换行符

直接修改你的sed替换逻辑,在捕获的内存数值后面加上\n,确保每个匹配项都自带换行:

loads=$(eval nvidia-smi | sed -nr 's/.*\s([0-9]+)MiB\s*\/\s*([0-9]+)MiB.*/\1 \2\n/p')

不管输入行是否有结尾换行,每个提取出的结果都会被强制加上换行符,最终echo $loads会输出两行独立的内容。

方法2:用a\命令强制追加换行

如果不想修改替换的核心逻辑,可以在每次打印匹配行后,用a\命令追加一个换行符(GNU sed中a\后无内容时会自动插入换行):

loads=$(eval nvidia-smi | sed -nr 's/.*\s([0-9]+)MiB\s*\/\s*([0-9]+)MiB.*/\1 \2/p; a\'')

这个方式相当于给每个输出的匹配行“补”上换行,逻辑更直观。

方法3:通用场景的G命令方案

如果需要处理混合有/无换行的复杂输入,可以利用G命令把保持空间的换行符(默认为空,执行G后会追加一个换行)加到模式空间末尾,再做去重处理:

loads=$(eval nvidia-smi | sed -nr 's/.*\s([0-9]+)MiB\s*\/\s*([0-9]+)MiB.*/\1 \2/; G; s/\n$//p')

这里G负责给行尾加换行,s/\n$//则避免输入行本身有换行时出现重复换行的问题,适配性更强。

为什么原始命令在GNU sed里会变成一行?

因为nvidia-smi的输出最后一行可能没有以换行符结尾(很多命令的输出都会有这种情况)。BSD sed会自动给每个输出的匹配行补全换行,而GNU sed严格遵循输入的换行状态——当输入行没有结尾换行时,p命令打印的内容也不带换行,导致两个匹配结果被直接拼接成一行。

修改命令后再测试,你会发现echo $loads的输出和BSD sed环境下完全一致:

18 11177
7 2000

内容的提问来源于stack exchange,提问作者PyariBilli

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.09 10:43:00