如何用bash、sed或awk将3个及以上空行压缩为2个?
压缩3个及以上连续空行为2个的实现方案
当然有办法啦!针对这个把3个及以上连续空行压缩成2个的需求,用Sed、Awk或者纯Bash脚本都能轻松搞定,我给你整理几个实用的方案:
1. 使用Sed实现
Sed是处理文本流的利器,核心思路是通过正则匹配连续的空行,把3个及以上的空行替换成2个。这个方案简洁高效,适合快速处理文本:
sed ':loop; /^$/{N; /^\n$/ba; s/\n\{3,\}/\n\n/}' input.txt
命令解释:
:loop:定义一个循环标签,方便后续跳转处理连续空行/^$/:匹配单独的空行{N; /^\n$/ba}:如果当前是空行,就读取下一行;如果新读取的行也是空行,就跳回loop标签继续合并空行s/\n\{3,\}/\n\n/g:当合并后出现3个及以上连续换行时,替换成2个换行
你也可以直接处理字符串,用管道快速测试:
echo -e "1\n2\n\n3\n\n\n4\n\n\n\n2\n\n3\n\n\n1\n" | sed ':loop; /^$/{N; /^\n$/ba; s/\n\{3,\}/\n\n/}'
2. 使用Awk实现
Awk的优势在于可以跟踪状态(比如连续空行的数量),逻辑更清晰,适合需要精细化控制的场景:
awk ' /^$/ { blank_count++ next } { if (blank_count > 0) { # 空行数量≥3就输出2个,否则输出实际数量的空行 printf "%s", blank_count >=3 ? "\n\n" : sprintf("\n%.0s", seq(1,blank_count)) blank_count = 0 } print $0 } END { # 处理文本末尾的连续空行 if (blank_count > 0) { printf "%s", blank_count >=3 ? "\n\n" : sprintf("\n%.0s", seq(1,blank_count)) } } ' input.txt
逻辑解释:
- 遇到空行时,增加
blank_count计数器,跳过后续处理 - 遇到非空行时,先根据之前的空行计数输出对应的换行(最多2个),然后重置计数器并输出当前行
END块专门处理文本末尾可能遗留的连续空行,避免遗漏
3. 纯Bash原生实现
如果不想依赖任何外部工具,用Bash的内置命令也能实现,通过逐行读取并维护空行计数器:
#!/bin/bash blank_count=0 # 逐行读取文本,保留换行符 while IFS= read -r line; do if [[ -z "$line" ]]; then ((blank_count++)) else # 输出累积的空行(最多2个) if ((blank_count > 0)); then if ((blank_count >= 3)); then echo -e "\n\n" else for ((i=0; i<blank_count; i++)); do echo done fi blank_count=0 fi echo "$line" fi done < input.txt # 处理文本末尾的连续空行 if ((blank_count > 0)); then if ((blank_count >= 3)); then echo -e "\n\n" else for ((i=0; i<blank_count; i++)); do echo done fi fi
使用说明:
把上面的代码保存为compress_blank_lines.sh,给它加执行权限(chmod +x compress_blank_lines.sh),然后运行./compress_blank_lines.sh即可处理指定的input.txt文件。
内容的提问来源于stack exchange,提问作者NiklasMan
相关产品推荐
相关产品推荐

