如何使用Bash脚本移除文件中的双换行符(LF)
移除sqlplus输出中多余双换行的通用方案
问题背景
已查阅Stack Overflow上关于sed移除双换行的相关问题,帖中给出的sed、awk解决方案均未生效。
通过sqlplus执行查询得到的输出文件会随机插入多余空行(双LF换行),无法提前预知查询返回的总行数,也无法预判双换行出现的具体位置,需要一套通用规则移除这类多余空行。
示例输出文件内容如下:
FOLDER1 filename_0.sem FOLDER1 filename_1.sem FOLDER1 filename_2.sem FOLDER1 filename_3.sem FOLDER1 filename_4.sem FOLDER1 filename_5.sem FOLDER1 filename_6.sem FOLDER1 filename_7.sem FOLDER1 filename_8.sem FOLDER1 filename_9.sem FOLDER1 filename_10.sem FOLDER1 filename_11.sem FOLDER1 filename_12.sem FOLDER1 filename_13.sem FOLDER1 filename_14.sem FOLDER1 filename_15.sem FOLDER1 filename_16.sem FOLDER1 filename_17.sem FOLDER1 filename_18.sem FOLDER1 filename_19.sem FOLDER1 filename_20.sem FOLDER1 filename_21.sem FOLDER1 filename_22.sem FOLDER2 filename_0.sem 24 rows selected.
已尝试的无效命令
此前执行过以下3种命令,均未达到预期效果:
- sed方案:
sed -i 's/\n\n/\n//g' file.txt > otherfile.txt
- perl方案:
perl -pe 's/\n\n//' file.txt > otherfile.txt
- awk方案:
awk 1 ORS='' file.txt > otherfile.txt
失效原因
这几个命令写法不符合工具的基础处理逻辑:
- sed默认逐行读取内容,读入内存的单行会自动剥离行尾换行符,根本无法匹配
\n\n的连续换行结构;同时命令中混用了-i原地修改参数和重定向输出,本身写法就存在冲突。 - perl加
-p参数默认也是逐行读取处理,和sed逻辑一致,无法捕获跨两行的连续换行。 - 直接将awk的ORS(输出记录分隔符)设置为空,会把所有正常的单换行也一并删除,最终所有内容会挤成单行,完全不符合需求。
可用通用方案
以下方案均可自动移除文件中所有多余空行(包括双换行、多换行),保留正常的单换行,不需要提前预知空行位置和文件总行数:
方案1:awk 实现(写法最简洁,兼容所有awk版本)
awk 'NF' file.txt > otherfile.txt
逻辑说明:NF是awk内置变量,代表当前行的字段数,空行没有任何有效字符,字段数为0会被直接过滤,非空的有效行正常输出。
如果需要同时过滤sqlplus自带的xx rows selected.提示行,可以直接扩展为:
awk 'NF && !/rows selected/' file.txt > otherfile.txt
方案2:sed 实现(兼容所有主流sed版本)
针对当前sqlplus输出纯空行的场景,用基础写法即可满足需求:
sed '/^$/d' file.txt > otherfile.txt
逻辑说明:匹配所有内容为空的行直接删除。如果存在连续多个空行、或空行夹带不可见空白字符的极端场景,可以用加强版:
sed '/^\s*$/d;N;/^\n$/D' file.txt > otherfile.txt
方案3:perl 实现
perl -00 -pe '' file.txt > otherfile.txt
逻辑说明:-00参数开启perl的段落读取模式,会自动将连续的多个空行压缩为单个换行,输出时自动剔除多余空行。
内容的提问来源于stack exchange,提问作者EOTheDev
相关产品推荐
相关产品推荐

