使用sed/awk合并以反斜杠结尾的行:Linux文本处理实战


阅读 8 次

问题场景

在Linux系统维护和脚本开发中,我们经常需要处理包含行续接符(反斜杠)的文本文件。比如从某些配置文件中提取多行参数,或者处理Makefile等构建脚本时,会遇到这样的格式:

CFLAGS = -Wall \
         -O2 \
         -DDEBUG

sed解决方案

使用sed的N命令可以高效处理这种情况:

sed ':a; /\\$/ { N; s/\\\n//; ba }' input.txt

这个命令的工作原理是:

  1. 创建标签:a
  2. 匹配以反斜杠结尾的行/\\$/
  3. 读取下一行N
  4. 删除反斜杠和换行符s/\\\n//
  5. 跳回标签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