免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
123下一页
最近访问板块 发新帖
查看: 5989 | 回复: 26
打印 上一主题 下一主题

请教,如何用sed匹配c函数 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2011-12-03 07:56 |只看该作者 |倒序浏览
如:

int test (int argc, char ** argv)
{
        int value = 3;

       if (value == 1)
       {
              printf("%d", value);
       } else {
             if()
             {
                     printf("%d\n", value);
             }
       }
      
       if (value > 0) {
              printf("%d\n", value);
      }

        return 0;
}

将此函数在下面复制一份并重命名为 test_a

期望效果:
int test (int argc, char ** argv)
{
        int value = 3;

       if (value == 1)
       {
              printf("%d", value);
       } else {
             if()
             {
                     printf("%d\n", value);
             }
       }
      
       if (value > 0) {
              printf("%d\n", value);
      }

        return 0;
}

int test_a (int argc, char ** argv)
{
        int value = 3;

       if (value == 1)
       {
              printf("%d", value);
       } else {
             if()
             {
                     printf("%d\n", value);
             }
       }
      
       if (value > 0) {
              printf("%d\n", value);
      }

        return 0;
}

关键是如何匹配test的最外层{ }

小菜鸟, 对脚本不太懂,希望大家指教

论坛徽章:
2
射手座
日期:2014-10-10 15:59:4715-16赛季CBA联赛之上海
日期:2016-03-03 10:27:14
2 [报告]
发表于 2011-12-03 09:34 |只看该作者
本帖最后由 yinyuemi 于 2011-12-03 10:02 编辑

回复 1# unbutun
针对你给出的例子:
  1. echo 'int test (int argc, char ** argv)
  2. {
  3.         int value = 3;

  4.        if (value == 1)
  5.        {
  6.               printf("%d", value);
  7.        } else {
  8.              if()
  9.              {
  10.                      printf("%d\n", value);
  11.              }
  12.        }

  13.        if (value > 0) {
  14.               printf("%d\n", value);
  15.       }

  16.         return 0;
  17. }'|sed -nr '
  18. /^[^ ]+.*\)$/{
  19. h;
  20. :a;
  21.   n;
  22.   H;
  23.   /\{/{
  24.     x;
  25.     s/^/#/;
  26.     x
  27.     };
  28.   /\}/{
  29.     x;
  30.     s/^#//;
  31.     /^[^#]/tb;
  32.     x;
  33.     }
  34.   ba;
  35. };
  36. :b;
  37. p;
  38. s/^([^ ]+ )([^ ]+)(.*\))/\1\2_a\3/p;'

  39. int test (int argc, char ** argv)
  40. {
  41.         int value = 3;

  42.        if (value == 1)
  43.        {
  44.               printf("%d", value);
  45.        } else {
  46.              if()
  47.              {
  48.                      printf("%d\n", value);
  49.              }
  50.        }

  51.        if (value > 0) {
  52.               printf("%d\n", value);
  53.       }

  54.         return 0;
  55. }
  56. int test_a (int argc, char ** argv)
  57. {
  58.         int value = 3;

  59.        if (value == 1)
  60.        {
  61.               printf("%d", value);
  62.        } else {
  63.              if()
  64.              {
  65.                      printf("%d\n", value);
  66.              }
  67.        }

  68.        if (value > 0) {
  69.               printf("%d\n", value);
  70.       }

  71.         return 0;
  72. }

复制代码

论坛徽章:
2
射手座
日期:2014-10-10 15:59:4715-16赛季CBA联赛之上海
日期:2016-03-03 10:27:14
3 [报告]
发表于 2011-12-03 10:11 |只看该作者
  1. sed -nr '
  2. /^[^ ]+.*\)$/,/return [^;]*;/{
  3.   H;
  4.   /return [^;]*;/{
  5.    x;
  6.    s/\n//;
  7.    s/$/\n}/p
  8.    s/^([^ ]+ )([^ ]+)(.*\))/\1\2_a\3/p;
  9.    s/.*//;
  10.    h
  11.   }
  12. }
  13. '
复制代码

论坛徽章:
3
2015年迎新春徽章
日期:2015-03-04 09:56:11数据库技术版块每日发帖之星
日期:2016-08-03 06:20:00数据库技术版块每日发帖之星
日期:2016-08-04 06:20:00
4 [报告]
发表于 2011-12-03 12:53 |只看该作者
用sed解决,的确有点复杂.
其实思路还是很简单,一个栈,{进,}出,直到栈空.awk可能比较明了一点

论坛徽章:
0
5 [报告]
发表于 2011-12-03 14:53 |只看该作者
回复 4# cjaizss


    哦,能否指点下,多谢

同时非常感谢yinyuemi,很热心,多谢你们

论坛徽章:
3
2015年迎新春徽章
日期:2015-03-04 09:56:11数据库技术版块每日发帖之星
日期:2016-08-03 06:20:00数据库技术版块每日发帖之星
日期:2016-08-04 06:20:00
6 [报告]
发表于 2011-12-03 15:12 |只看该作者
回复  cjaizss


    哦,能否指点下,多谢

同时非常感谢yinyuemi,很热心,多谢你们
unbutun 发表于 2011-12-03 14:53



    打个比方,{代表进栈,}代表出栈,
    那么
  s/[^{}]//g过滤所有的空格;
   然后
  :a;
   s/\{\}//;
   ta;
   之后就只剩下多余的{或者}

论坛徽章:
3
2015年迎新春徽章
日期:2015-03-04 09:56:11数据库技术版块每日发帖之星
日期:2016-08-03 06:20:00数据库技术版块每日发帖之星
日期:2016-08-04 06:20:00
7 [报告]
发表于 2011-12-03 15:13 |只看该作者
打个比方,{代表进栈,}代表出栈,
    那么
  s/[^{}]//g过滤所有的空格;
   然后
  :a;
   s ...
cjaizss 发表于 2011-12-03 15:12



    如果不考虑字符串里的{或者}就很容易去做到了.
   "{"
   这种情况要考虑的话就要更加麻烦一点

论坛徽章:
1
技术图书徽章
日期:2013-09-25 21:06:29
8 [报告]
发表于 2011-12-03 16:02 |只看该作者
回复 3# yinyuemi


    请问下,第3行的H 会不会对第5行的x造成影响呢?  {}里面的hold空间和外面的hold空间一致吗?

论坛徽章:
3
2015年迎新春徽章
日期:2015-03-04 09:56:11数据库技术版块每日发帖之星
日期:2016-08-03 06:20:00数据库技术版块每日发帖之星
日期:2016-08-04 06:20:00
9 [报告]
发表于 2011-12-03 16:36 |只看该作者
以上是原理,我就不写数学证明了.
现在来实现编码,
假设编程习惯不像以下这样恶心:
int func(){}int func2{}
函数写到一行去,那么以下是可以使用的代码

  1. linux-0gt0:/tmp/test # cat 2.sed
  2. #!/bin/sed -nrf
  3. /int[ \t]+test[ \t]*\(/!d
  4. h

  5. :a
  6. n
  7. H
  8. /\{/ {
  9.         s/[^{}]//g
  10.         H
  11.         bb
  12. }
  13. ba

  14. :b
  15. n
  16. H
  17. :c
  18. s/[^{}]//g
  19. tc #clear s
  20. H
  21. x
  22. s/(\n[^\n]*)(\n[^\n]*)\n([^\n]*)$/\2\1\3/
  23. td
  24. :d
  25. s/(\n[^\n]*)\{\}([^\n]*)$/\1\2/
  26. td
  27. /\n$/ {
  28.         s/\n$//p
  29.         s/^[ \t]*int[ \t]+test/&_a/p
  30.         q
  31. }
  32. x
  33. bb
  34. linux-0gt0:/tmp/test # cat test.c
  35. #include <stdio.h>
  36. int test()
  37. {
  38.         {   int i=0;{printf("%d",i);}
  39.                 printf("%d\n",1);for(i=0;i<100;i++){printf("%d",i);{int j;for(j=0;j<100;j++){printf("test");}}}
  40.         }
  41. }
  42. int main()
  43. {
  44.         return 0;
  45. }
  46. linux-0gt0:/tmp/test # ./2.sed test.c
  47. int test()
  48. {
  49.         {   int i=0;{printf("%d",i);}
  50.                 printf("%d\n",1);for(i=0;i<100;i++){printf("%d",i);{int j;for(j=0;j<100;j++){printf("test");}}}
  51.         }
  52. }
  53. int test_a()
  54. {
  55.         {   int i=0;{printf("%d",i);}
  56.                 printf("%d\n",1);for(i=0;i<100;i++){printf("%d",i);{int j;for(j=0;j<100;j++){printf("test");}}}
  57.         }
  58. }

复制代码

论坛徽章:
3
2015年迎新春徽章
日期:2015-03-04 09:56:11数据库技术版块每日发帖之星
日期:2016-08-03 06:20:00数据库技术版块每日发帖之星
日期:2016-08-04 06:20:00
10 [报告]
发表于 2011-12-03 16:38 |只看该作者
yinyuemi 发表于 2011-12-03 10:11

  1. linux-0gt0:/tmp/test # cat test.c
  2. #include <stdio.h>
  3. int test()
  4. {
  5.         {   int i=0;{printf("%d",i);}
  6.                 printf("%d\n",1);for(i=0;i<100;i++){printf("%d",i);{int j;for(j=0;j<100;j++){printf("test");}}}
  7.         }
  8. }
  9. int main()
  10. {
  11.         return 0;
  12. }
  13. linux-0gt0:/tmp/test # cat test.c | sed -nr '

  14. /^[^ ]+.*\)$/,/return [^;]*;/{

  15.   H;

  16.   /return [^;]*;/{

  17.    x;

  18.    s/\n//;

  19.    s/$/\n}/p

  20.    s/^([^ ]+ )([^ ]+)(.*\))/\1\2_a\3/p;

  21.    s/.*//;

  22.    h

  23.   }

  24. }

  25. '
  26. int test()
  27. {
  28.         {   int i=0;{printf("%d",i);}
  29.                 printf("%d\n",1);for(i=0;i<100;i++){printf("%d",i);{int j;for(j=0;j<100;j++){printf("test");}}}
  30.         }
  31. }
  32. int main()
  33. {
  34.         return 0;
  35. }
  36. int test()
  37. {
  38.         {_a   int i=0;{printf("%d",i);}
  39.                 printf("%d\n",1);for(i=0;i<100;i++){printf("%d",i);{int j;for(j=0;j<100;j++){printf("test");}}}
  40.         }
  41. }
  42. int main()
  43. {
  44.         return 0;
  45. }

复制代码
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP