![awk:匹配头文件中枚举块内的代码块](https://linux22.com/image/158897/awk%EF%BC%9A%E5%8C%B9%E9%85%8D%E5%A4%B4%E6%96%87%E4%BB%B6%E4%B8%AD%E6%9E%9A%E4%B8%BE%E5%9D%97%E5%86%85%E7%9A%84%E4%BB%A3%E7%A0%81%E5%9D%97.png)
我正在尝试解析 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 /,/}/!b
enum
保留- -}
范围之外的所有行/#ifdef/!b
也不要碰里面的所有东西,直到#ifdef
:loop
是的,一旦我们遇到了#ifdef
,我们就需要循环N
现在我们开始追加行.../#endif/!bloop
直到我们找到#endif
- 然后
d
删除我们收集的所有内容#ifdef
以及#endif
我们收集的内容