使用 sed 或 awk 如何删除某条线周围的图案



我需要删除某行周围的图案:

#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循环是风格还是取决于您的操作系统提供的内容。

最新更新