2013-05-16 111 views
3

如何将awk变量传递给bash命令在awk内运行?如何将awk变量传递给bash命令

我使用awk来计算线程的运行总和为每一个特定的过程,但我想用每个PID访问/proc/$pid文件系统。

标记为破线的线不正确,因为$pid不存在。

如何导出awk变量pid到shell命令我得到awk来运行?

(增加了可读性换行符)

$ ps -ALf | grep $PROC | grep -v grep | \   # get each pid 
    awk '{threads[$2]+=1} END \     # count num threads per pid 
     { \ 
      for (pid in threads) \ 
       "cat /proc/$pid/cwd"|getline cwd; \ # get 'cwd' (**broken**) 
       print cwd ": " threads[pid] \  # display 'cwd' and num threads 
     }' 
+0

为什么不在awk中做这么多? – Johnsyweb

+2

不要做'grep ... | grep -v ... | awk ...',因为awk可以完成grep(s)的工作。在linux上,你可以使用'ps -C $ PROC'来只显示一个特定的进程(es)。 – TrueY

回答

2

你可以做一大堆的没有任何grep s链路这样的:

  • -v proc="${PROC}"环境变量${PROC}分配到awk变量:

    值得注意
    % ps -ALf | awk -v proc="${PROC}" ' 
    $0 ~ proc && !/awk/ { 
        threads[$2] += 1 
    } 
    END { 
        for (pid in threads) { 
         "readlink /proc/" pid "/cwd" | getline dir 
         printf "%d: %d %s\n", pid, threads[pid], dir 
         dir="" 
        } 
    }' 
    

    有几件事情,proc

  • "readlink /proc/" pid "/cwd"连接三串。 awk中不需要任何级联运算符。
  • dir=""复位dir变量,如果符号链接周围的环中的下一个时间是不可读。
2

awk不进行变量插值字符串内,你只要连接具有字符串(就像你在print语句来完成)的变量。

awk '{threads[$2]+=1} END     # count num threads per pid 
    { 
     for (pid in threads) 
      ("cat /proc/" pid "/cwd")|getline cwd; # get 'cwd' (**broken**) 
      print cwd ": " threads[pid]  # display 'cwd' and num threads 
    }' 

你也不需要所有的反斜杠。带引号的字符串中的换行符不需要转义(其中一些甚至不在换行符之前,后面有注释)。

4

你不能猫/proc/$pid/cwd它是一个符号链接到一个目录。解决符号链接的一种方法是使用来自coreutils的readlink

这里是TrueY巴尔梅尔使用位的工作例如:

ps -C $PROC | 
awk '{ t[$1] } END { for(p in t) { "readlink -f /proc/" p "/cwd" | getline c; print c } }' 

几件事情需要注意:

  • 管兼作续行字符。
  • 引用数组条目来创建它就足够了(t[$1])。