awk:匹配头文件中枚举块内的代码块

awk:匹配头文件中枚举块内的代码块

我正在尝试解析 C++ 标头以删除枚举内的任何 #ifdef。我需要这个,因为我正在使用的 headerParser 模块存在跳过任何带有 #ifdef 的枚举的错误。

我有一个 shell 脚本来收集文件并准备它。然后调用一个 python 脚本来生成最终输出。 python 文件是通用的,因此我只需要在 shell 脚本内执行“#ifdef”块清理。

文本部分如下所示:

  typedef enum fixedsample
{
element 1,
element 2,
element 3,
#ifdef XYZ
element 4,
element 5,
#endif
} FIXEDNAME;

我不需要 ifdef 中的元素,因此需要删除它。此外,枚举名称“fixedsample”和“FIXEDNAME”对于任何文件都是正确的,不会有任何变化。

awk 可以用于此目的吗?任何帮助都非常感谢。

编辑:“typedef enum ConstantName”和“}CONSTANT;”将出现在所有文件中。因此 #ifdef 只需要在该块内搜索。不会删除其他 #ifdef。

答案1

awk可以使用范围和标志来做到这一点,例如:

awk '/enum fixedsample/,/} FIXEDNAME/ { e=1 } e && /^#ifdef/,/^#endif/ { next } { e=0; print }' foo.hpp

sed版本甚至不需要标志,只需嵌套范围,因此范围#ifdef ... #endif内的每个范围enum ... }都会被d删除:

sed '/enum fixedsample/,/} FIXEDNAME/{; /^#ifdef/,/^#endif/d; }' foo.hpp

在您的实际版本中,您应该使用更精确的模式来减少误报的可能性。

答案2

在任何语言语法中乱用正则表达式几乎都不是一个好主意。它非常脆弱,会因为最轻微的原因(比如#ifdef注释掉一行)而陷入混乱。用另一个可能有错误的解析器修复一个有错误的解析器……至少很奇怪。

如果你理解了这个问题,你可以继续阅读。

在某些情况下,这可能有助于删除整个#ifdef块(顺便说一句,您确定要像未定义一样对待它吗?):

sed '/ enum /,/}/!b
  /#ifdef/!b
  :loop
  N
  /#endif/!bloop
  d' file.h

解释:

  • / enum /,/}/!benum保留- -}范围之外的所有行
  • /#ifdef/!b也不要碰里面的所有东西,直到#ifdef
  • :loop是的,一旦我们遇到了#ifdef,我们就需要循环
  • N现在我们开始追加行...
  • /#endif/!bloop直到我们找到#endif
  • 然后d删除我们收集的所有内容#ifdef以及#endif我们收集的内容

相关内容