免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
打印 上一主题 下一主题

awk 递归支持的如何? [复制链接]

论坛徽章:
0
31 [报告]
发表于 2007-01-19 14:51 |只看该作者
原帖由 Edengundam 于 2007-1-19 13:29 发表


awk 对于没有赋值的参数变量初始化为空, 如果这个变量不在参数列表就跑去访问全局变量(可能没有初始化). 所以局部变量不需要给他传值. 如下
[code]
function a(para, local)
{
     body
}

a(a);
[/ ...

!!原来如此,可以这么用!

论坛徽章:
0
32 [报告]
发表于 2007-01-19 14:53 |只看该作者
原帖由 一梦如是 于 2007-1-19 14:39 发表
如果awk提供将字节甚至行推回缓冲区的函数,getline的功能才能更完善

怎么跑到 getline 去了,梦兄思维跳跃啦
不过为什么要推回缓冲区?打个比方我才能明白

论坛徽章:
0
33 [报告]
发表于 2007-01-19 15:35 |只看该作者
  1. #!/bin/bash
  2. ps -eo pid,ppid |
  3. awk '
  4. function listchildpid(pid){
  5. #       print "ppid = "pid;
  6.         if ($2 == pid) {
  7.                 print "    pid = "$1;
  8. #               print "==="$2"===";
  9.                 listchildpid($1);
  10.         }
  11.         }
  12. listchildpid(upid);
  13. ' upid=$1

复制代码

我在想我这个方法的问题,它的问题是当递归调用listchildpid时,判断($2 == pid)并不是遍历每一行,而是判断当前行的$2,因此永远是false,所以递归调用的函数执行不到if语句块中的内容。
想在函数中加一句“if (pid != upid) getline;”取下面的行,但没有推回函数,getline的行就无法再次使用了。例如pid为2的进程没有子进程,getline后判断出它没有子进程后应该将它推回,否则第一次调用的函数判断($2 == pid)时就已经跳过这一行了。

呵呵,已经复杂化了,别想我这个思路了,行不通的不应该死钻牛角。

自觉
http://bbs.chinaunix.net/viewthr ... page%3D1&page=2
我16楼的第二段代码思路不错,简单清晰,而且“有趣”,这个问题的确不该死守递归的方法。

论坛徽章:
0
34 [报告]
发表于 2007-01-19 15:40 |只看该作者
原帖由 一梦如是 于 2007-1-19 15:35 发表
[code]#!/bin/bash
ps -eo pid,ppid |
awk '
function listchildpid(pid){
#       print "ppid = "pid;
        if ($2 == pid) {
                print "    pid = "$1;
#         ...



进程派生关系就是一颗树...树型结构用递归是最直接的办法. ^_^

这里awk兄只是遇到了点语法问题, 并不是逻辑复杂.

论坛徽章:
0
35 [报告]
发表于 2007-01-19 15:44 |只看该作者
他的是递归调用时改变全局变量的问题,但我上面那个不是,它是awk在循环语句段封装的行为导致的,我们无法干预循环语句段的行为。

如果是C,“树型结构用递归是最直接的办法”这句话一点没错,可惜awk的遍历整个文件是awk内部实现的,我们无法让递归调用的函数再遍历一次文件。因此在不用数组作中转的前提下,似乎没办法在循环语句段实现真正意义上的递归。

可以说,我上面那段代码其实不是递归,因为它在第一次调用时和递归调用时,行为并不相同。

[ 本帖最后由 一梦如是 于 2007-1-19 15:59 编辑 ]

论坛徽章:
0
36 [报告]
发表于 2007-01-19 16:05 |只看该作者
原帖由 一梦如是 于 2007-1-19 15:44 发表
他的是递归调用时改变全局变量的问题,但我上面那个不是,它是awk在循环语句段封装的行为导致的,我们无法干预循环语句段的行为。

如果是C,“树型结构用递归是最直接的办法”这句话一点没错,可惜awk的遍历整 ...



说实话...我还得花时间去思考你的代码在不同时候的特点....
先写我的文档...等下研究...有点复杂...
有时候算法直白好些>_<嘿嘿

论坛徽章:
0
37 [报告]
发表于 2007-01-19 16:39 |只看该作者
原帖由 一梦如是 于 2007-1-19 15:44 发表
.. 可惜awk的遍历整个文件是awk内部实现的,我们无法让递归调用的函数再遍历一次文件 ...

我把有用的信息先保存到数组里面了
如果反复的读所有信息,就算能实现也没效率,而且不能提高可读性 ^_^

论坛徽章:
0
38 [报告]
发表于 2007-01-19 16:41 |只看该作者
原帖由 Edengundam 于 2007-1-19 16:05 发表



说实话...我还得花时间去思考你的代码在不同时候的特点....
先写我的文档...等下研究...有点复杂...
有时候算法直白好些>_<嘿嘿

赶快写你的文档。。
任何时候优先考虑可读性,不赞成复杂~

论坛徽章:
0
39 [报告]
发表于 2007-01-19 16:42 |只看该作者
原帖由 一梦如是 于 2007-1-19 15:35 发表
[code]#!/bin/bash
ps -eo pid,ppid |
awk '
function listchildpid(pid){
#       print "ppid = "pid;
        if ($2 == pid) {
                print "    pid = "$1;
#         ...

Eden 15F 的代码,还是递归 ^_^

论坛徽章:
0
40 [报告]
发表于 2007-01-19 16:47 |只看该作者
还有个简单的办法可以实现这个递归的功能
就是对于每一个进程存它的父进程号,存到数组中.
然后遍历所有进程,判断是否此进程的某个祖先进程为我们预先定义的进程
如果是,输出此进程,否则,对下一个进程进行如上判断.
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP