3

目的

Linux では、使用可能なシステム メモリを表すエンド ユーザーにわかりやすい文字列を取得しようとしています。

例:

Your computer has 4 GB of memory.

成功基準

私はこれらの側面をエンドユーザーにとって使いやすいと考えています (同意しないかもしれません):

  • 1G1.0G( 1Vs 1.0)より読みやすい

  • 1GB1G( GBVs G)より読みやすい

  • 1 GB1GB(space-separated単位)より読みやすい

  • memoryRAMDDRまたはDDR3(専門用語なし)よりも読みやすい

出発点

procps-ng無料ユーティリティには、人間向けのオプションがあります。

-h, --human
    Show all output fields automatically scaled to shortest three digit unit
    and display the units of print out.  Following units are used.
        B = bytes
        K = kilos
        M = megas
        G = gigas
        T = teras
    If unit is missing, and you have petabyte of RAM or swap, the number is
    in terabytes and columns might not be aligned with header.

だから私はそこから始めることにしました:

> free -h
             total       used       free     shared    buffers     cached
Mem:          3.8G       1.4G       2.4G         0B       159M       841M
-/+ buffers/cache:       472M       3.4G
Swap:         4.9G         0B       3.9G

3.8G有望そうに聞こえるので、今私がしなければならないのは...

必要な手順

  • 人間が読める文字列を含む行の出力をフィルター処理します (つまりMem:)

  • 行の中央からメモリの合計を取り出します (つまり3.8G)

  • 数と測定単位を解析します (すなわち3.8G)

  • 文字列を自分の好みに合わせてフォーマットして表示する (例: GGB, ...)

私の試み

free -h | \
  awk  '/^Mem:/{print $2}' | \
    perl -ne '/(\d+(?:\.\d+)?)(B|K|M|G|T)/ && printf "%g %sB\n", $1, $2'

出力:

3.8 GB

望ましい解決策

  • gawkだけを使用したいのですが、方法がわかりません

  • 文字列から「 float」を解析する方法があれば、より良い方法を使用してください。

  • 新しいサイズの導入で一致が不必要に壊れるとしても、「認識された大きさの文字だけ」という細かい一致は気にしません。(B|K|M|G|T)

  • 私はとして%g出力4.0していまし4たが、これは、これらのコメントについてどのように感じているかによって、同意できない場合があります: https://unix.stackexchange.com/a/70553/10283

私の質問、要約すると

  • 上記のみでお願いできますawkか?
  • perl厳密さを保ったまま、それよりもエレガントに書けるでしょうか?

覚えて:

I am a beginner robot. Here to learn. :]

アンディ・レスターから学んだこと

私自身の利益のためにここに要約します:できれば学習を固めるためです。

たとえば、このgawk :

echo foo bar baz | awk '{print $2}'

perlでは次のように記述できます。

echo foo bar baz | perl -ane 'print "$F[1]\n";'

gawk に相当するものがない限り、私はgawkの方--field-separatorが好きだと思います が、もちろんすべてをperlで行う方がクリーンで効率的です。(同等のものはありますか?)


編集:実際、これは存在することを証明し、 gawk-Fと同じです:

echo ooxoooxoooo | perl -Fx -ane 'print join "\n", @F'

出力:

oo
ooo
oooo

ありがとう、アンディ!


4

3 に答える 3

3

はい、あなたはこれを awk のみで行うことができると確信していますが、私は Perl 派なので、Perl のみで行う方法を次に示します。

(B|K|M|G|T)使用する代わりに[BKMGT]

Perl を使用-lして、入力から改行を自動的に削除し、出力に追加します。

Awk にストリッピングの一部を行わせ、残りを Perl に行わせる理由は見当たりません。Perl の -a でフィールドの自動分割を行うことができます。

free -hからの出力が正確に何であるかはわかりfreeません(私にはオプションがありません-h)ので、これを推測しています

free -h | \
perl -alne'/^Mem:/ && ($F[1]=~/(\d+(?:\.\d+)?)[BKMGT]/) && printf( "%g %sB", $1, $2)'
于 2013-03-30T02:38:48.733 に答える
0

別の長い Perl の回答:

free -b | 
perl -lane 'if(/Mem/){ @u=("B","KB","MB","GB"); $F[2]/=1024, shift @u while ($F[2]>1024); printf("%.2f %s", $F[2],$u[0])}'
于 2013-03-30T03:02:30.673 に答える