50

Unixシステムで値の列の合計をすばやく簡単に計算する方法があると確信していますが(awkまたはxargsおそらく何かを使用して)、行ごとに行を解析するシェルスクリプトを書くことが唯一の方法です現時点での心。

たとえば、次のコマンドを変更して、SEGSZ 列 (70300) の合計を計算して表示する最も簡単な方法は何ですか?

ipcs -mb | head -6
IPC status from /dev/kmem as of Mon Nov 17 08:58:17 2008
T         ID     KEY        MODE        OWNER     GROUP      SEGSZ
Shared Memory:
m          0 0x411c322e --rw-rw-rw-      root      root        348
m          1 0x4e0c0002 --rw-rw-rw-      root      root      61760
m          2 0x412013f5 --rw-rw-rw-      root      root       8192
4

11 に答える 11

87
ipcs -mb | tail +4 | awk '{ sum += $7 } END { print sum }'

またはテールなし:

ipcs -mb | awk 'NR > 3 { sum += $7 } END { print sum }'

bc で awk を使用すると、任意の長い結果が得られます (クレジットはJouni K.):

ipcs -mb | awk 'NR > 3 { print $7 }' | paste -sd+ | bc
于 2008-11-17T15:14:20.023 に答える
13

次のように、計算文字列を作成してbcにフィードしようとします。

  1. 数字を含む行をgrepします
  2. 各行の数字の前 (および後) のすべての文字を削除します
  3. xargs結果 (空白で区切られた数値の文字列を取得するため)
  4. 空白を「+」文字に変換します
  5. 食欲旺盛です

ipcs -mb | grep -w '^m ' | sed 's/^.*\s//' | xargs | tr ' ' + | bc

これはawkソリューションよりも少し長いように見えますが、奇妙なawkコードを読めない (そして理解できない) すべての人にとって、これは理解しやすいかもしれません... :-)

bcがインストールされていない場合は、上記の手順 5 で二重括弧を使用して結果を計算できます。

  • echo $(( $(ipcs -mb | grep -w '^m ' | sed 's/^.*\s//' | xargs | tr ' ' +) ))また
  • SUM=$(( $(ipcs -mb | grep -w '^m ' | sed 's/^.*\s//' | xargs | tr ' ' +) ))また
  • (( SUM=$(ipcs -mb | grep -w '^m ' | sed 's/^.*\s//' | xargs | tr ' ' +) ))

二重括弧の前後の間隔はオプションです。

于 2010-06-02T10:50:05.953 に答える
4

すべての列を単純に合計するユーティリティ スクリプトがあります。通常、1 行の出力から必要なものを簡単に取得できます。おまけとして、いくつかの SI サフィックスが認識されます。

#!/usr/bin/awk -f
# Sum up numerical values by column (white-space separated)
#
# Usage:  $0 [file ...]
#
# stern, 1999-2005

{
    for(i = 1; i <= NF; ++i) {
        scale = 1
        if ($i ~ /[kK]$/) { scale = 1000 }
        if ($i ~ /[mM]$/) { scale = 1000*1000 }
        if ($i ~ /[gG]$/) { scale = 1000*1000*1000 }
        col[i] += scale * $i;
    }
    if (NF > maxnf) maxnf = NF;
}

END {
    for(i = 1; i <= maxnf; ++i) { printf " %.10g", col[i] }
    print "";
}

カスタム フィールド セパレータを使用した例:

$ head /etc/passwd | addcol -F:
0 0 45 39 0 0 0
于 2009-02-03T09:28:00.637 に答える
3

この質問はやや古いことは知っていますが、ここに「私の」回答が表示されないため、それでも投稿することにしました。私はの組み合わせで行きます

  • テール(必要な行を取得するため)
  • tr (複数の連続したスペースを 1 つに縮小するため)
  • 切り取り (必要な列のみを取得するため)
  • 貼り付け (各行を+記号で連結するため)
  • bc (実際の計算を行うため)

ipcs私のシステムでは出力が得られないため、次の方法でデモを行いdfます。

# df
Filesystem     1K-blocks    Used Available Use% Mounted on
rootfs          33027952 4037420  27312812  13% /
udev               10240       0     10240   0% /dev
tmpfs             102108     108    102000   1% /run
/dev/xvda1      33027952 4037420  27312812  13% /
tmpfs               5120       0      5120   0% /run/lock
tmpfs             204200       0    204200   0% /run/shm
/dev/xvda1      33027952 4037420  27312812  13% /var/www/clients/client1/web1/log
/dev/xvda1      33027952 4037420  27312812  13% /var/www/clients/client1/web2/log
/dev/xvda1      33027952 4037420  27312812  13% /var/www/clients/client1/web3/log
/dev/xvda1      33027952 4037420  27312812  13% /var/www/clients/client1/web4/log
/dev/xvda1      33027952 4037420  27312812  13% /var/www/clients/client2/web5/log
/dev/xvda1      33027952 4037420  27312812  13% /var/www/clients/client2/web6/log
# df | tail -n +2 | tr -s ' ' | cut -d ' ' -f 2 | paste -s -d+ | bc
264545284

私のシステムでこの特定の計算を行うことは実際には意味がありませんが、概念を示しています。

このソリューションのすべての部分は他の回答で示されていますが、その組み合わせではありません。

于 2015-02-16T22:42:37.647 に答える
2

Python ソリューション

#!/usr/bin/env python
text= file("the_file","r")
total= 0
for line in text:
    data = line.split()
    if data[0] in ('T', 'Shared', 'IPC'): continue
    print line
    segsize= int(data[6])
    total += segsize
print total

ほとんどの Linux ディストリビューションには Python が含まれています。

stdin をパイプラインの一部として処理したい場合は、

import sys
total = 0
for line in sys.stdin:
   ...etc...

常に 3 つのヘッダー行があると仮定したい場合:

import sys
total = 0
for line in sys.stdin.readlines()[3:]:
    total += int(line.split()[6])
print total

一発ギャグ:

import sys; print sum( [int(line.split()[6]) for line in sys.stdin.splitlines()[3:]] )
于 2008-11-17T15:14:25.747 に答える
1

あなたはそれをどんなオンラインawkリファレンスでも調べることができます:

ipcs | awk '
BEGIN { sum = 0 }
/0x000000/ { sum = sum + $2 }
END {print sum}'
于 2008-11-17T15:28:52.177 に答える
1

データを実行することから始めることができますcut-これにより、少なくとも列が削除されます。

grep次に、それを にパイプして、非数値を取り除くことができるはずです。

それから...まあ、それではわかりません。それを にパイプすることは可能かもしれませんbc。そうでない場合は、シェル スクリプトに渡して各項目を追加することができます。

tr改行 ( ) をスペース ( ) に変更し、それ\nxargs を介してスクリプトにパイプし、入力がなくなるまでループして、それぞれを追加すると、答えが得られる場合があります。

したがって、次のようなものです。

cat <whatever> | cut -d'\t` -f7 | grep -v <appropriate-character-class> | tr '\n' ' ' | xargs script-that-adds-arguments

cutフラグが少し間違っているかもしれませんが、manあなたの友達です:)

于 2008-11-17T15:13:14.487 に答える
0

上記の Python ワンライナーをありがとう!. ドライブの使用済みスペースを簡単に確認するのに役立ちました。これは、シェルと Python の混合ワンライナーです。これは、デバイス /dev/sda の使用済みスペースをメガバイト単位でカウントします。私がそれを見つけるまでに時間がかかったので、誰かがこれも役に立つと思うかもしれません.

df -h -B 1M | grep dev/sda | tr -s ' '| cut -d' ' -f3 |python -c "import sys; print sum([int(num) for num in sys.stdin.readlines()])"

以上の Python / 以下のシェル:

 df -h -B 1M | python -c "import sys; print sum([int(l.split()[2]) for l in sys.stdin.readlines() if '/dev/sda' in l])"

再度、感謝します!

于 2009-03-13T15:14:22.573 に答える