我需要删除某行周围的图案:
#undef LZZ_INLINE
#ifdef LZZ_ENABLE_INLINE
#include "somename.inl"
#endif
应该变成:
#include "somename.inl"
我事先不知道somename
。如何以通用方式使用例如 sed 或 awk 来完成此操作?
如果文件大小允许读取一次将其加载到内存中,您可以
sed -i.bk ':a;$!{N;ba}; s/#undef LZZ_INLINEn#ifdef LZZ_ENABLE_INLINEn(#include [^n]*)n#endif/1/g' input.file
如果一切顺利,请删除.bk
文件:)
请尝试此单行是否适合您:
awk '/#undef LZZ_INLINE/{next;} /#ifdef LZZ_ENABLE_INLINE/{x=1;next;}x&&/#endif/{x=0;next;}1' file
添加到名为fix.sed的文件中
/^#undef LZZ_INLINE/{
N
N
N
s/.*(#include "[^"]*").*/1/
}
像这样运行:
sed -f fix.sed 您的原始文件
假设答案@glennjackman发布:
awk '/#undef LZZ_INLINE/{next} /#ifdef LZZ_ENABLE_INLINE/{x=1;next}x&&/#endif/{x=0;next} 1' file
是正确的,您只想就地更新输入文件,这里有一种方法可以使用awk执行此操作:
awk '/#undef LZZ_INLINE/{next} /#ifdef LZZ_ENABLE_INLINE/{x=1;next}x&&/#endif/{x=0;next} {out[++nr]=$0} END{close(FILENAME); for (i=1;i<=nr;i++) print out > FILENAME}' file
(即将1
替换为{out[++nr]=$0} END{close(FILENAME); for (i=1;i<=nr;i++) print out > FILENAME}
)
这是另一个:
awk '/#undef LZZ_INLINE/{next} /#ifdef LZZ_ENABLE_INLINE/{x=1;next}x&&/#endif/{x=0;next} {print > "/tmp/""FILENAME""" } END{system("mv /tmp/""FILENAME"" ""FILENAME"""}' file
(即将1
替换为{print > "/tmp/""FILENAME""" } END{system("mv /tmp/""FILENAME"" ""FILENAME"""}
)
如何实现它有一些变化,但基本思想只是缓冲输出,直到您完成读取输入文件然后覆盖输入文件。无论哪种方式...
我应该提到的另一个变体是创建一个 tmp INPUT 文件,它看起来像这样:
awk '
BEGIN{
tmp="/tmp/"" ARGV[1] """
while ( (getline var < ARGV[1]) > 0 ) {
print var > tmp
}
close(tmp)
out = ARGV[1]
ARGV[1] = tmp
}
/#undef LZZ_INLINE/{next} /#ifdef LZZ_ENABLE_INLINE/{x=1;next}x&&/#endif/{x=0;next} {print > out}' file
您使用的是系统("mv...")还是getline循环是风格还是取决于您的操作系统提供的内容。