0

出力前に 1 回だけ印刷する必要がある数値が 2 回印刷されるという問題があります。最も関連性の高いコンテンツを強調しますが、コンテキストを示すために、スクリプト全体を提供します。

#!/bin/bash

ps auxa の出力を配列にロードします。

N=0
for i in $(ps aux | awk '{print $11,$4}' | grep -v 0.0 | grep -v MEM | sort) ; do

array[$N]="$i"

let "N= $N + 1"
done

ここで、配列を 2 つの配列に分割します

N=0

for i in `seq 0 ${#array[@]}`; do

if [ $(( $i % 2 )) -eq 0 ]; then arrayb[$N]=${array[$i]} ; else arrayc[$N]=${array[$i]} ;fi

let "N= $N + 1"

done

ここで、重複したエントリを結合しようとします (複雑な変数名の一部をご容赦ください。トラブルシューティングを試みて暗闇の中で写真を撮っていました)。

N=0
c=0

for i in `seq 0 ${#arrayb[@]}`; do

let "B= $N - 1"

A=`echo ${arrayb[$B]} | tr -d '\n'`
B=`echo ${arrayb[$N]} | tr -d '\n'`

#A=${arrayb[$B]}
#B=${arrayb[$N]}

ここで、前者の配列要素が後者と等しいかどうかを確認します。その場合は、結合して削除します。

#if [ "$A" = "$B" ]; then 
#arrayc[$N]=$(bc <<< ${arrayc[$N]}+${arrayc[$B]}); unset arrayb[$B];unset arrayc[$B]; echo trololo
#echo derp
#fi

重要な部分はこれです。echo $cそれから私echo $A $B。ただし、私の出力は次のとおりです。

0
 awk
1
awk 
2
 -bash
3
-bash 
4
 -bash

次のような場合:

0
 awk
awk 
2
 -bash
-bash 
3

echo $c
echo -n "$A" "$B"

echo ""
let "c=$c+1"


let "N= $N + 1"
done

私が頭を包むことができないのは、それがすべて同じループであるとき、次にどのように印刷されるかですa。どんな援助でも大歓迎です。cbc

4

1 に答える 1

1

最初のforループは次のように単純化できます。

array=( $(ps aux | awk '$4 != 0.0 && $4 !~ /MEM/ {print $11,$4}' | sort) )

単一のフラグメントとして記述した場合、2 番目のループは次のようになります。

N=0
for i in `seq 0 ${#array[@]}`
do
    if [ $(( $i % 2 )) -eq 0 ]
    then arrayb[$N]=${array[$i]}
    else arrayc[$N]=${array[$i]}
    fi
    ((N++))
done

反復ごとに N をインクリメントしているためarrayb[0]、名前が含まれてarrayc[1]おり、対応するメモリ使用量が含まれています。おそらく次のものを使用する必要があります。

for i in `seq 0 ${#array[@]}`
do
    if [ $(( $i % 2 )) -eq 0 ]
    then arrayb[$((i/2))]=${array[$i]}
    else arrayc[$((i/2))]=${array[$i]}
    fi
done

ただし、最初の代入と 2 番目のループを組み合わせたほうがよいでしょう。

ps aux | awk '$4 != 0.0 && $4 !~ /MEM/ {print $11,$4}' | sort |
while read name memory
do
     arrayb+=($name)
     arrayc+=($memory)
done

ここでの唯一の問題は、配列が終了するサブシェルに設定されていることです。幸いなことに、その問題を回避するためにプロセス置換bashを提供します。

arrayb=()
arrayc=()
while read name memory
do
     arrayb+=($name)
     arrayc+=($memory)
done < <(ps aux | awk '$4 != 0.0 && $4 !~ /MEM/ {print $11,$4}' | sort)

次に、コードは現在次のように記述されています。

N=0
c=0

for i in `seq 0 ${#arrayb[@]}`; do

    let "B= $N - 1"

    A=`echo ${arrayb[$B]} | tr -d '\n'`
    B=`echo ${arrayb[$N]} | tr -d '\n'`
    echo $c
    echo -n "$A" "$B"
    echo ""
    let "c=$c+1"
    let "N= $N + 1"

done

arrayb2回アクセスして無視するので、問題がありますarrayc。また、2番目のループの元のコードで不要なインクリメントを元に戻すために、ゆがみを経験しているようです。

バックティックの使用は、一般的に悪い考えです。代わりに使用$(...)します。tr -d '\n'不要なはずです。echo -n "$A" "$B"すぐに続くの使用echo ""は奇妙です:echo "$A" "$B"十分でしょうか?

for i in $(seq 0 ${#arrayb[@]})
do
    echo "${arrayb[$i]}" "${arrayc[$i]}"
done

したがって、これまでに提供されたスクリプトを次のように減らすことができます。

arrayb=()
arrayc=()
while read name memory
do
     arrayb+=($name)
     arrayc+=($memory)
done < <(ps aux | awk '$4 != 0.0 && $4 !~ /MEM/ {print $11,$4}' | sort)

for i in $(seq 0 ${#arrayb[@]})
do
    echo "${arrayb[$i]}" "${arrayc[$i]}"
done

ここから、一致するインデックスに比較可能な値が含まれるように整理された 2 つの配列arraybとを引き続き使用できます。arrayc

于 2013-10-28T02:57:44.513 に答える