
左側の階層を最適に保ち、右側のサイズ値を並べ替えるにはどうすればよいですか?
また、同時にサイズを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_num
0.088
space_mib=${space#* }
space_mib
MiB
printf
%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/'
以前の答えとほぼ同じように始まります。ただし、以下はsed
2つの部分からなるパイプを通してすべてをパイプします。
s/(\..*) /\100 /
これは小数点(\.
)とそれに続くすべての文字(.*
)と一致し、空白文字は含まれません。次に、一致する文字列全体をスペース()の前の部分、\1
2つのゼロ、およびスペースに置き換えます。 (と言うこともできますが、s/(\..*)( )/\100\2/
同じことをしたかもしれません。)これはと0.088 MiB
に変わります0.08800 MiB
。データにある場合に変更されます。しかし、後ろに数字がなくても、すべての数字に小数点があるとします。 (また、文字列、、などにはピリオドがないとします。)0.0 MiB
0.000 MiB
42. MiB
42.00 MiB
mtr
pkgconfig
libiconv
私たちはこれを確実にするためにこれを行う必要があります。はい各数字には小数点以下の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
答え2
ご存知のように、printf
これは印刷物の書式設定に最適なツールです。すでに学んだように、%s
これは出力文字列の形式です。
%20s
右揃えで左が空白で埋められた(必要な場合)、20文字の長さの文字列を出力します。
%-20s
逆の場合も同様です。 20文字の長さの文字列が出力され、左揃えになり、右側が空白で埋められます(必要な場合)。たとえば、次のコマンドは
printf "%-20s%s\n" "mtr" "0.088 MiB"
printf "%-20s%s\n" " pkgconfig" "0.615 MiB"
printf "%-20s%s\n" " libiconv" "6.270 MiB"
︙
出力を生成します
mtr 0.088 MiB
pkgconfig 0.615 MiB
libiconv 6.270 MiB
︙
したがって、次のコマンドを使用して目的の結果を得ることができます。
port rdeps mtr 2>/dev/null | sed -E "1 s/.*of (.*) @.*/\1/" |
while IFS= read -r line
do
printf "%-20s%s\n" "$line" \
"$(port space --units MiB --total $line 2>/dev/null | cut -d ' ' -f 1-2)"
done
$
私は、妥当な理由がない限り、シェルコマンドとスクリプトから参照(変数など)を常に引用する必要があることを推奨します。$(…)
表現を引用符で囲みました。ただし、$line
先行スペースが含まれているため
port space --units MiB --total "$line"
動作しません。
もちろん、必要に応じて上記の複合コマンドをすべて1行に入れることができ、必要20
に応じて調整する必要があります。