【问题标题】:How to pass a bash array to awk properly如何正确地将 bash 数组传递给 awk
【发布时间】:2017-05-09 15:09:49
【问题描述】:

我的目标是创建一个脚本,列出前 5 个最消耗内存的进程及其 PID、Mem ifnos 和 Swap 消耗。部分地,我已经完成了。 但现在,我想在 bash/awk 中将其作为一个输出。 awk 看不到传递的 bash 数组。 这是我的方法:

echo -e "PID\t%CPU\t%MEM\tMEM\tSWAP\tPROCESS"
pids=($(ps aux | awk 'BEGIN { FS = "[ \t]+" } ; {pid[$11]+=$2}; {mem[$11]+=int($6/1024)}; {cpuper[$11]+=$3};{memper[$11]+=$4}; END {for (i in mem) {print " "pid[i]"\t",cpuper[i]"%\t",memper[i]"%\t",mem[i],i}}' | sort -k4nr | head -n 5|awk '{print $1}'))

swap=()
j=0
for i in "${pids[@]}"
do
   :
        if [ -f "/proc/$i/status" ]
        then
                swap[j]=$(awk '/Tgid|VmSwap|Name/{printf $2" "}END{ print ""}' < /proc/$i/status|awk '{print int($3/1024)}')
        else
                swap[j]=0
        fi
        j+=1
done

echo ${swap[@]}

ps aux | awk -v sw="${swap[*]}" -v sep="[:]" 'BEGIN { n = split(sw, a, sep); FS = "[ \t]+" } ; {pid[$11]+=$2}; {mem[$11]+=int($6/1024)}; {cpuper[$11]+=$3};{memper[$11]+=$4}; END {for (i in mem) {print " "pid[i]"\t",cpuper[i]"%\t",memper[i]"%\t",mem[i]" MB\t",a[i]" MB",i}}' | sort -k4nr | head -n 5

输出是

PID     %CPU    %MEM    MEM     SWAP    PROCESS
 57551   6.3%    4.7%    9076 MB          MB java
 478839  1.2%    0%      657 MB   MB /usr/sbin/httpd
 54418   1.6%    0.2%    524 MB   MB /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.121-0.b13.el7_3.x86_64/jre/bin/java
 63047   0.1%    0%      47 MB    MB /usr/sbin/mysqld
 237334  0%      0%      22 MB    MB sshd:

我们发现表 swap 中缺少信息,这似乎在 var sw 拆分为 var a

【问题讨论】:

  • 试试swap[j].... awk ... &lt;( /proc/$i/status|awk '{print int($3/1024)}') )。祝你好运。
  • 看不到传递的 bash 数组是什么意思?你得到什么输出?你在期待什么?

标签: linux bash shell awk args


【解决方案1】:

这里,

awk -v sw="${swap[*]}" -v sep="[:]" 'BEGIN { n = split(sw, a, sep); ... }

您似乎试图在冒号上拆分 sw。但是"${swap[*]}" 会生成一个字符串,其中数组swap 的元素与IFS 的第一个字符相连接,默认情况下是一个空格。

因此,您需要在使用"${swap[*]}" 之前将IFS 更改为冒号,或者将分隔符设置为awk 一侧的空格。

$ arr=(foo bar) ; IFS=:
$ awk -v par="${arr[*]}" 'BEGIN{ n = split(par, a, ":"); 
    for (x in a) {printf "%s %s\n", x, a[x]}; exit }' 
1 foo
2 bar

【讨论】:

  • awk -v par="$(IFS=:;echo "${arr[*]}")" ... 避免修改当前 shell 的 IFS
【解决方案2】:

有关信息 ps 带有一些选项可能会给出结果

ps -eo pid,%cpu,%mem,vsz,sz,cmd --sort -vsz | head

还有

j=0
j+=1

仅适用于typeset -i j

【讨论】:

    猜你喜欢
    • 2011-12-05
    • 1970-01-01
    • 2012-07-14
    • 2012-01-23
    • 2014-04-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-05
    相关资源
    最近更新 更多