如何去除 C 文件中的 `#ifdef MACRO ... #endif' 段落

用Perl的扩展正则友情赞助一个
复制内容到剪贴板
代码:
[0 No.2089 huan@huan ~/tmp]$ cat txt
@@@@@@@@@@@@@@@@@@@@@@
#ifdef a
aaa
    #ifdef bbb
    bbb
        #ifdef ccc
        ccc
        #endif
    #endif
#endif
@@@@@@@@@@@@@@@@@@@@@@

[0 No.2090 huan@huan ~/tmp]$ perl -0777 -lpe ' 1 while s{#ifdef.*(?!#ifdef)#endif}{}s' txt
@@@@@@@@@@@@@@@@@@@@@@

@@@@@@@@@@@@@@@@@@@@@@

[0 No.2091 huan@huan ~/tmp]$
如果要修改文件而不是输出到STDOUT
复制内容到剪贴板
代码:
[0 No.2091 huan@huan ~/tmp]$ perl -0777 -lpi -e ' 1 while s{#ifdef.*(?!#ifdef)#endif}{}s' txt

[0 No.2092 huan@huan ~/tmp]$ cat txt
@@@@@@@@@@@@@@@@@@@@@@

@@@@@@@@@@@@@@@@@@@@@@

[0 No.2093 huan@huan ~/tmp]$
      
为什么要删除?
你只要在所有文件中引一个文件,在那个文件中定义一上预定义一个CONFIG_A就可以了。
删除为了什么?      
原因很简单,一驱除多余代码,而上级不希望这部分代码让别人看到      
Foo.c[/FONT]内容为[/FONT][/SIZE]
复制内容到剪贴板
代码:
[/SIZE][/FONT][/SIZE][/FONT]
[FONT=Times New Roman][SIZE=3]121321312[/SIZE][/FONT]
[FONT=Times New Roman][SIZE=3]#ifdef TEST_MDA_B[/SIZE][/FONT]
[FONT=Times New Roman][SIZE=3]123123[/SIZE][/FONT]
[FONT=Times New Roman][SIZE=3]#ifdef TEST_MDA_B[/SIZE][/FONT]
[SIZE=3][FONT=Times New Roman]       static int test_mda_b(unsigned char val, unsigned char reg)[/FONT][/SIZE]
[SIZE=3][FONT=Times New Roman]       {[/FONT][/SIZE]
[SIZE=3][FONT=Times New Roman]       unsigned long flags;[/FONT][/SIZE]
[SIZE=3][FONT=Times New Roman]       spin_lock_irqsave(&mda_lock, flags);[/FONT][/SIZE]
[SIZE=3][FONT=Times New Roman]       return val;[/FONT][/SIZE]
[SIZE=3][FONT=Times New Roman]       }[/FONT][/SIZE]
[FONT=Times New Roman][SIZE=3]#endif[/SIZE][/FONT]
[FONT=Times New Roman][SIZE=3]123123[/SIZE][/FONT]
[FONT=Times New Roman][SIZE=3]#endif[/SIZE][/FONT]
[FONT=Times New Roman][SIZE=3]fdhyfghfg[/SIZE][/FONT]
[FONT=Times New Roman][SIZE=3]5465454[/SIZE][/FONT]
[FONT=Times New Roman][SIZE=3][FONT=Verdana][SIZE=2]
[/SIZE][/FONT][/SIZE][/FONT]
[/SIZE][/FONT]
[/SIZE][/FONT]
执行脚本[/SIZE][/FONT]
复制内容到剪贴板
代码:
[/SIZE][/FONT][/SIZE][/FONT][/FONT]
[FONT=Times New Roman][SIZE=3]#! /bin/bash[/SIZE][/FONT]
[FONT=Times New Roman][SIZE=3]level=0[/SIZE][/FONT]
[FONT=Times New Roman][SIZE=3]IFS=$'\n\r'[/SIZE][/FONT]
[FONT=Times New Roman][SIZE=3]while read -r line; do[/SIZE][/FONT]
[SIZE=3][FONT=Times New Roman]    if [[ "$line" == \#ifdef* ]]; then[/FONT][/SIZE]
[SIZE=3][FONT=Times New Roman]        ((level++))[/FONT][/SIZE]
[SIZE=3][FONT=Times New Roman]        while read -r line; do[/FONT][/SIZE]
[SIZE=3][FONT=Times New Roman]            if [[ "$line" == \#if* ]]; then[/FONT][/SIZE]
[SIZE=3][FONT=Times New Roman]                ((level++))[/FONT][/SIZE]
[SIZE=3][FONT=Times New Roman]            elif [[ "$line" == \#endif ]]; then[/FONT][/SIZE]
[SIZE=3][FONT=Times New Roman]                ((level--))[/FONT][/SIZE]
[SIZE=3][FONT=Times New Roman]                if [ $level -lt 0 ]; then[/FONT][/SIZE]
[SIZE=3][FONT=Times New Roman]                    echo "Error" 1>&2[/FONT][/SIZE]
[SIZE=3][FONT=Times New Roman]                    exit 1[/FONT][/SIZE]
[SIZE=3][FONT=Times New Roman]                fi[/FONT][/SIZE]
[SIZE=3][FONT=Times New Roman]                if [ $level = 0 ]; then[/FONT][/SIZE]
[SIZE=3][FONT=Times New Roman]                    break[/FONT][/SIZE]
[SIZE=3][FONT=Times New Roman]                fi[/FONT][/SIZE]
[SIZE=3][FONT=Times New Roman]            fi[/FONT][/SIZE]
[SIZE=3][FONT=Times New Roman]        done[/FONT][/SIZE]
[SIZE=3][FONT=Times New Roman]        continue[/FONT][/SIZE]
[SIZE=3][FONT=Times New Roman]    fi[/FONT][/SIZE]
[SIZE=3][FONT=Times New Roman]    echo "$line"[/FONT][/SIZE]
[FONT=Times New Roman][SIZE=3]done[/SIZE][/FONT]
[FONT=Times New Roman][SIZE=3] [FONT=Times New Roman][SIZE=3][FONT=Verdana][SIZE=2]
[/SIZE][/FONT][/SIZE][/FONT][/SIZE][/FONT]
[/SIZE][/FONT]
[/SIZE][/FONT]
结果[/SIZE][/FONT]
121321312[/SIZE][/FONT]
[/SIZE][/FONT]
121321312[/SIZE][/FONT]
fdhyfghfg[/SIZE][/FONT]
[/SIZE][/FONT]
[/SIZE][/FONT]
[/SIZE][/FONT]
[/SIZE][/FONT]
符合逻辑及要求[/FONT],[/FONT]但若将[/FONT]Foo.c[/FONT]改为[/FONT][/SIZE]
复制内容到剪贴板
代码:
[/SIZE][/FONT][/SIZE][/FONT] [/SIZE][/FONT]
[FONT=Times New Roman][SIZE=3]121321312[/SIZE][/FONT]
[FONT=Times New Roman][SIZE=3]#ifdef TEST_MDA_B[/SIZE][/FONT]
[FONT=Times New Roman][SIZE=3]123123[/SIZE][/FONT]
[FONT=Times New Roman][SIZE=3]#ifdef TEST_MDA_B[/SIZE][/FONT]
[SIZE=3][FONT=Times New Roman]       static int test_mda_b(unsigned char val, unsigned char reg)[/FONT][/SIZE]
[SIZE=3][FONT=Times New Roman]       {[/FONT][/SIZE]
[SIZE=3][FONT=Times New Roman]       unsigned long flags;[/FONT][/SIZE]
[SIZE=3][FONT=Times New Roman]       spin_lock_irqsave(&mda_lock, flags);[/FONT][/SIZE]
[SIZE=3][FONT=Times New Roman]       return val;[/FONT][/SIZE]
[SIZE=3][FONT=Times New Roman]       }[/FONT][/SIZE]
[FONT=Times New Roman][SIZE=3]#endif[/SIZE][/FONT]
[FONT=Times New Roman][SIZE=3]123123[/SIZE][/FONT]
[FONT=Times New Roman][SIZE=3]#endif[/SIZE][/FONT]
[FONT=Times New Roman][SIZE=3]fdhyfghfg[/SIZE][/FONT]
[FONT=Times New Roman][SIZE=3] [FONT=Times New Roman][SIZE=3][FONT=Verdana][SIZE=2]
[/SIZE][/FONT][/SIZE][/FONT][/SIZE][/FONT]
少了最后一行[/FONT],[/FONT]执行结果却变为[/FONT][/SIZE]
121321312[/SIZE][/FONT]
[/SIZE][/FONT]
[/SIZE][/FONT]
请问这是为什么[/FONT]?[/FONT][/SIZE]
为什么[/FONT]endif[/FONT]后有[/FONT]2[/FONT]行执行正确[/FONT][/SIZE]
endif[/FONT]后只有[/FONT]1[/FONT]行时执行会出错[/FONT]?[/FONT][/SIZE]
[/SIZE][/FONT]
[/SIZE][/FONT]
[/SIZE][/FONT]
[/SIZE][/FONT]      
此问题已经通过在处理文件前对文件末尾加一空行解决
现在新的问题是,假如在#ifdef #endif段中有#else的情况如何解决
即希望下列
复制内容到剪贴板
代码:
E
#ifdef A
B
#else
C
#endif
D
处理结果为
E
C
D

不知该如何编写脚本(其中需加判断#ifdef #endif段中是否有#else若无的话分支跳到上一脚本便可处理,若有的话如何处理)谢谢      
请问老大这个else怎么处理谢谢      
[QUOTE=michaelzhang;571451]请问老大这个else怎么处理谢谢[/QUOTE]
根据前面的讨论, 不觉得这个问题很难的样子, 请充分发挥您个人的主观能动性, 俺的时间也很宝贵的, 忙啊       
我不清楚你写的脚本中lt这个变量是什么意思,谢谢      
lt => little then      
那这句echo "Error" 1>&2
中的1,和&2是什么意思?谢谢大大们,我还是个菜鸟,真不好意思啊