丸め込み

丸め込み

左側の階層を最適に保ち、右側のサイズ値を並べ替えるにはどうすればよいですか?
また、同時にサイズを1桁または2桁に丸めたいと思います。
試してみましたが、printfこの形式を維持する方法はわかりません。

$ port rdeps mtr 2>/dev/null | sed -E "1 s/.*of (.*) @.*/\1/" | while IFS= read -r line; do echo -e "$line" \\t\\t\\t\\t $(port space --units MiB --total $line 2>/dev/null | cut -d ' ' -f 1-2); done
mtr                  0.088 MiB
  pkgconfig                  0.615 MiB
    libiconv                 6.270 MiB
      gperf                  0.0 MiB
  glib2                  46.092 MiB
    xz               1.679 MiB
      gettext                24.825 MiB
        expat                1.109 MiB
        ncurses                  15.171 MiB
    libxml2                  10.405 MiB
      zlib               0.721 MiB
    libffi               0.141 MiB
    pcre                 5.954 MiB
      bzip2                  0.647 MiB
      libedit                0.795 MiB

これは次のようにする必要があります

mtr                          0.08 MiB
  pkgconfig                  0.61 MiB
    libiconv                 6.27 MiB
      gperf                  0.00 MiB
  glib2                     46.09 MiB
    xz                       1.67 MiB
      gettext               24.82 MiB
        expat                1.10 MiB
        ncurses             15.17 MiB
    libxml2                 10.40 MiB
      zlib                   0.72 MiB
    libffi                   0.14 MiB
    pcre                     5.95 MiB
      bzip2                  0.64 MiB
      libedit                0.79 MiB

ベストアンサー1

これを行う方法はいくつかあります。

丸め込み

ご存知のように、printfこれは印刷物の書式設定に最適なツールです。  %f「浮動小数点数」、つまり整数ではない数、つまり小数部分を含む数を出力するための形式です。すべてのprintf形式と同様に、次の数字(整数!)は、% スペースを含むことができる形式化された出力の合計長を指定します。数字の後にピリオド(.)と表示する小数点以下の桁数を指定する別の数字(小数点の右側の数字)。たとえば、次のコマンドは

printf "%12.2f\n" 1000000
printf "%12.2f\n" 1000
printf "%12.2f\n" 1
printf "%12.2f\n" 1.2345
printf "%12.2f\n" 1.6789

出力を生成します

  1000000.00
     1000.00
        1.00
        1.23
        1.68

1.6789ありますので参考にしてください丸め到着する1.68

したがって、次のコマンドを使用して目的の結果を得ることができます。

port rdeps mtr 2>/dev/null | sed -E "1 s/.*of (.*) @.*/\1/" |
     while IFS= read -r line
     do
         space="$(port space --units MiB --total $line 2>/dev/null | cut -d ' ' -f 1-2)"
         space_num=${space% *}
         space_mib=${space#* }
         printf "%-20s%12.2f %s\n" "$line" "$space_num" "$space_mib"
     done

このspace=$(…)コマンドは、port space私たちが使用したコマンドに代わるものにすぎませんが、結果(例えば0.088 MiB、のような形)は一時変数に割り当てられていますspace。次に、空白文字の前の部分(数字、この場合など)にspace_num=${space% *}設定し、空白文字の後の部分(単位など)に設定します。最後に、数字を小数点以下の2桁まで表示するためにすべての部分を一緒に貼り付け、最も近い100分の1桁に丸め、小数点に整列しました(前の例のように)。あなたのデータについて、これは次のとおりですspace_num0.088space_mib=${space#* }space_mibMiBprintf %12.2f

mtr                         0.09 MiB
  pkgconfig                 0.62 MiB
    libiconv                6.27 MiB
      gperf                 0.00 MiB
  glib2                    46.09 MiB
    xz                      1.68 MiB
      gettext              24.83 MiB
        expat               1.11 MiB
        ncurses            15.17 MiB
    libxml2                10.40 MiB
      zlib                  0.72 MiB
    libffi                  0.14 MiB
    pcre                    5.95 MiB
      bzip2                 0.65 MiB
      libedit               0.80 MiB

0.088 MiB丸めになるので参考にしてください0.09 MiB

また、実際に計算する必要がないようにspace_mib常にに設定されていることに注意してください。MiB

port rdeps mtr 2>/dev/null | sed -E "1 s/.*of (.*) @.*/\1/" |
     while IFS= read -r line
     do
         space_num="$(port space --units MiB --total $line 2>/dev/null | cut -d ' ' -f 1)"
         printf "%-20s%12.2f %s\n" "$line" "$space_num" "MiB"
     done

同じ上記と。

切り捨て込み

単に数字を切り捨てるには、数字ではなく文字列として扱うことをお勧めします。このコマンド

port rdeps mtr 2>/dev/null | sed -E "1 s/.*of (.*) @.*/\1/" |
     while IFS= read -r line
     do
         printf "%-30s%s\n" "$line" \
                  "$(port space --units MiB --total $line 2>/dev/null | cut -d ' ' -f 1-2)"
     done | sed -E -e 's/(\..*) /\100 /' -e 's/(.{25}) *(....\...).*( .*)/\1\2\3/'

以前の答えとほぼ同じように始まります。ただし、以下はsed2つの部分からなるパイプを通してすべてをパイプします。

  • s/(\..*) /\100 /
    これは小数点(\.)とそれに続くすべての文字(.*)と一致し、空白文字は含まれません。次に、一致する文字列全体をスペース()の前の部分、\12つのゼロ、およびスペースに置き換えます。 (と言うこともできますが、s/(\..*)( )/\100\2/同じことをしたかもしれません。)これはと0.088 MiBに変わります0.08800 MiB。データにある場合に変更されます。しかし、後ろに数字がなくても、すべての数字に小数点があるとします。 (また、文字列、、などにはピリオドがないとします。)0.0 MiB0.000 MiB42. MiB42.00 MiBmtrpkgconfiglibiconv

    私たちはこれを確実にするためにこれを行う必要があります。はい各数字には小数点以下の2桁以上があります。gperfこの修正を行う前はそうではありませんでした。

  • s/(.{25}) *(....\...).*( .*)/\1\2\3/
    .{25}.........................の略語で、任意の25文字です。これは、最も長く(たとえばlibiconv)最も深くインデントされた文字列をキャプチャするのに十分な長さのようです。次に、任意の文字(.*)、実際には単に空白の束であることを願っています。次に、....\...4つの文字、小数点、および2つの文字をさらに一致させます。スペースの数がを超える場合は、9999小数点の左側の4桁以上を一致するように変更する必要があります。次に、必要な数の文字(.*)、つまり小数点の後の最初の2桁の後のすべての数字です。その後、スペースと残りの行(( .*))を願ってください MiB。次に、フラグメントを文字列(適切な先行スペースと後続のスペースを含む)、数字(十分な先行スペースを含む)に再組み立てします。.\2、単位が続きます。

このコマンドの出力は次のとおりです。

mtr                         0.08 MiB
  pkgconfig                 0.61 MiB
    libiconv                6.27 MiB
      gperf                 0.00 MiB
  glib2                    46.09 MiB
    xz                      1.67 MiB
      gettext              24.82 MiB
        expat               1.10 MiB
        ncurses            15.17 MiB
    libxml2                10.40 MiB
      zlib                  0.72 MiB
    libffi                  0.14 MiB
    pcre                    5.95 MiB
      bzip2                 0.64 MiB
      libedit               0.79 MiB

0.088 MiBで切ります0.08 MiB

もちろん、必要に応じて上記の複合コマンドをすべて1行に入れることができ、必要に応じて幅定数(12、、20など)25を調整する必要があります。30

おすすめ記事