我想用来修改生成 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
如果您首先能够弄清楚如何防止跨行拆分,您也许可以避免第一步。
参考:
- Sed 单行解释,第一部分:文件间距、编号以及文本转换和替换,39. 如果一行以反斜杠“\”结尾,则将其追加到下一行