Mac平台Sed无法匹配换行符,如何实现每3行合并为一行?
解决Mac下Sed合并每3行的问题
问题回顾
你有一个千行文本文件,格式如下:
9 9 9 9 9 9 9 9 9 9 9 9 9 9
需要将每3行合并为一行,得到:
9 9 9 9 9 9 9 9 9 9 9 9 9 9
你尝试用Sed替换换行符但无效,因为Mac自带的是BSD Sed,和GNU Sed处理换行符的逻辑不同。
可行解决方案
1. 用Mac自带的BSD Sed实现
Sed默认按行处理,单个模式空间里只有当前行,无法直接匹配换行符,需要用N命令把后续行读入模式空间。执行以下命令:
sed -e 'N;N;s/\n/ /g' test.txt
N;N:连续两次将下一行读入模式空间,此时模式空间包含3行内容(带两个换行符)s/\n/ /g:将模式空间内所有换行符替换为空格,完成3行合并- Sed会自动循环处理剩余行,刚好每3组生成一行
2. 用Awk实现(跨平台通用)
Awk处理行更灵活,适合这种按行数分组的需求:
awk '{printf "%s ", $0} NR%3==0 {print ""}' test.txt
printf "%s ", $0:不换行输出当前行内容,末尾加空格NR%3==0 {print ""}:当行号是3的倍数时,输出换行符,完成一组3行的合并
如果担心最后一行可能有多余空格,可以用下面的命令处理:
awk '{line = line $0 " "} NR%3==0 {print substr(line, 1, length(line)-1); line=""} END {if(line!="") print substr(line,1,length(line)-1)}' test.txt
3. 直接在Vim中处理(无需外部命令)
打开文件后,执行以下循环命令,直接合并每3行:
:let i=1 | while i <= line('$') | execute i.','.i+2.'join' | let i +=3 | endwhile
- 从第1行开始,每次选中
i到i+2行,执行join合并操作,然后i增加3,直到处理完所有行
为什么你的原命令无效?
Mac的BSD Sed中,s/\n/X/3无法工作的原因:
- Sed默认模式空间只包含当前行,换行符不在当前行的内容里,根本无法匹配
/3表示替换当前行内第3次匹配的内容,但当前行没有换行符,自然无效果
内容的提问来源于stack exchange,提问作者user1284303
相关产品推荐
相关产品推荐

