使用 sed 进行多组捕获/修改

使用 sed 进行多组捕获/修改

我想用来修改生成 C/C++ 文件依赖关系图sed的输出。gcc -MM

输入看起来像:

ThreadCrash.o : ThreadCrash.cpp ThreadCrash.h hdr1.h \
 ../inc/hdr2.h ../inc/hdr3.h \
 ../inc/hdr4.h ../inc/hdr4.h

我需要让它看起来像:

ThreadCrash.o : \
ThreadCrash.cpp \
ThreadCrash.h \
hdr1.h \
../inc/hdr2.h \
../inc/hdr3.h \
../inc/hdr4.h \
../inc/hdr4.h

对于替代品的“查找”部分,我一直在尝试“重复”捕获组,(.*)*但无法弄清楚如何形成替换字符串。

我不依赖于 sed 因此任何简单的方法,例如awk等,都将受到极大的欢迎。

谢谢!

答案1

在每个 UNIX 机器上的任何 shell 中使用任何 awk:

$ cat tst.awk
BEGIN { RS="" }
{
    gsub(/\\/,"")
    printf "%s ", $1
    for (i=2; i<NF; i++) {
        printf "%s \\\n", $i
    }
    print $NF
}

$ awk -f tst.awk file
ThreadCrash.o : \
ThreadCrash.cpp \
ThreadCrash.h \
hdr1.h \
../inc/hdr2.h \
../inc/hdr3.h \
../inc/hdr4.h \
../inc/hdr4.h

答案2

删除行开头的空格,然后用 space-backslash-newline-char 序列替换除冒号或反斜杠之外的任何空格:

使用 GNU sed:

sed -E 's/^ //; s/ ([^:\\])/ \\\n\1/g'

答案3

尽管这看起来违反直觉,但实际上最简单的方法可能是将依赖关系缝合回单行(通过重新连接延续),然后通过匹配水平空白序列(带有可选的冒号)再次将其分开。

所以给出

$ cat input
ThreadCrash.o : ThreadCrash.cpp ThreadCrash.h hdr1.h \
 ../inc/hdr2.h ../inc/hdr3.h \
 ../inc/hdr4.h ../inc/hdr4.h

然后

$ sed -e :a -e '/\\$/N; s/\\\n//; ta' input
ThreadCrash.o : ThreadCrash.cpp ThreadCrash.h hdr1.h  ../inc/hdr2.h ../inc/hdr3.h  ../inc/hdr4.h ../inc/hdr4.h

最后

$ sed -e :a -e '/\\$/N; s/\\\n//; ta' input | sed -r 's/[[:blank:]]+(: )?/ \1\\\n/g'
ThreadCrash.o : \
ThreadCrash.cpp \
ThreadCrash.h \
hdr1.h \
../inc/hdr2.h \
../inc/hdr3.h \
../inc/hdr4.h \
../inc/hdr4.h

gcc -MM如果您首先能够弄清楚如何防止跨行拆分,您也许可以避免第一步。

参考:

相关内容