Unix环境下将单个空格替换为两个空格(禁用awk、perl工具)
解决方案:Unix下替换单个空格为两个(保留多空格)
我来给你几个纯Unix原生工具的实现方案,完全满足你的要求——只从标准输入读取、输出到标准输出,不用awk/perl,还能精准替换单个空格,多空格原样保留:
方案1:用sed(最常用、高效的方式)
sed是Unix系统标配的流编辑器,完全符合你的限制。根据你用的是GNU sed还是BSD sed(比如macOS自带的),可以用下面两种写法:
通用兼容版
sed -e 's/\([^ ]\) \([^ ]\)/\1 \2/g' -e 's/^ / /' -e 's/ $/ /'
扩展正则简洁版
如果你的sed支持扩展正则(大部分现代系统都支持),可以用更简洁的写法:
sed -E 's/(^|[^ ]) ($|[^ ])/\1 \2/g'
命令逻辑解释
- 通用版里的第一个规则:
s/\([^ ]\) \([^ ]\)/\1 \2/g专门匹配两个非空格字符之间的单个空格,把中间的空格换成两个,\1和\2用来保留前后的非空格内容,避免被误替换。 - 后面两个规则分别处理行开头的单个空格和行结尾的单个空格,确保这些边缘场景也被覆盖。
- 扩展正则版用
(^|[^ ]) ($|[^ ])把开头/非空格+单个空格+结尾/非空格的情况统一匹配,一次替换就完成所有场景,写法更简洁。
方案2:纯shell循环(适合特殊场景)
如果出于某些原因不想直接用sed,也可以用shell的read循环配合处理(不过效率比sed低,适合小文本场景):
while IFS= read -r line; do # 先处理中间的单个空格 processed=$(echo "$line" | sed 's/\([^ ]\) \([^ ]\)/\1 \2/g') # 再处理开头和结尾的单个空格 processed=$(echo "$processed" | sed -e 's/^ / /' -e 's/ $/ /') echo "$processed" done
注:纯shell的参数替换(比如${line// / })会把所有空格都换成两个,没法区分单个和多个,所以sed还是绕不开的核心工具。
测试示例
输入:
San Diego Hello World foo test bar
输出:
San Diego Hello World foo test bar
内容的提问来源于stack exchange,提问作者Micki
相关产品推荐
相关产品推荐

