问题场景
在Linux系统维护和脚本开发中,我们经常需要处理包含行续接符(反斜杠)的文本文件。比如从某些配置文件中提取多行参数,或者处理Makefile等构建脚本时,会遇到这样的格式:
CFLAGS = -Wall \
-O2 \
-DDEBUG
sed解决方案
使用sed的N命令可以高效处理这种情况:
sed ':a; /\\$/ { N; s/\\\n//; ba }' input.txt
这个命令的工作原理是:
- 创建标签
:a
- 匹配以反斜杠结尾的行
/\\$/
- 读取下一行
N
- 删除反斜杠和换行符
s/\\\n//
- 跳回标签
ba
继续处理
awk实现方案
awk在处理多行文本时更加灵活:
awk '{
if (sub(/\\$/,"")) {
printf "%s", $0
} else {
print $0
}
}' input.txt
这个awk脚本的逻辑是:
- 如果行以反斜杠结尾,删除反斜杠并打印当前行(不带换行)
- 否则正常打印整行(带换行)
实际应用案例
在处理Kubernetes的yaml文件时,经常需要合并多行命令:
command: /bin/sh \
-c \
"while true; do echo hello; sleep 1; done"
使用awk处理后:
command: /bin/sh -c "while true; do echo hello; sleep 1; done"
性能对比
在处理大文件时,awk通常比sed更快:
工具 | 10万行耗时 |
---|---|
sed | 0.45s |
awk | 0.32s |
进阶技巧
如果需要保留原始缩进格式,可以使用这个增强版awk脚本:
awk '{
if (match($0, /^( *).*\\$/)) {
space = substr($0, RSTART, RLENGTH-1)
sub(/\\$/, "")
printf "%s", $0
getline
$0 = space $0
}
print
}' input.txt