私はハードドライブ上のファイルのサイズを正確なバイト単位で見つけようとしていますが、サイズが大きくなりすぎると数値がすべて変わってしまいます(1.998329e + 12など)。これをやめたり、これを正確なバイトに変換したりできますか?
コマンドは次のとおりです。
ls -lR | grep -v '^d' | awk '{total += $5} END {print "Total:", total}'
正確なバイトの画像:
奇妙な数字の画像:
du -sb
は、ディレクトリの大きさに関係なく正確なバイト数を正しく表示します。ntfs
なので、ext4としてフォーマットし、ファイルをコピーしてみました。結果はntfsと同じです。問題は、MAWK(UbuntuにインストールされたAWKバリアント)がデフォルトで2147483647
(231-1)科学表記法:
% awk -W version
mawk 1.3.3 Nov 1996, Copyright (C) Michael D. Brennan
compiled limits:
max NF 32767
sprintf buffer 2040
% printf '2147483647\n' | awk '{x += $1; print x}'
2147483647
% printf '2147483648\n' | awk '{x += $1; print x}'
2.14748e+09
printf
*の代わりに、フォーマット指定子でprint
を使用できます。
printf '2147483648\n' | awk '{x += $1; printf "%.0f\n", x}'
% printf '2147483648\n' | awk '{x += $1; printf "%.0f\n", x}'
2147483648
あなたの場合:
ls -lR | grep -v '^d' | awk '{total += $5} END {printf "Total:%.0f\n", total}'
ls -lR |
grep -v '^d' |
awk '
{
total += $5
}
END {
printf "Total:%.0f\n", total
}
'
これにより、AWKはtotal
を科学表記ではなく10進表記で印刷するように強制されます。
ただし、別の注意事項では、 ls
を解析しないでください。
より繊細な方法は、find
+ stat
を使用することです。
find . -type f -exec stat -c '%s' {} + | awk '{total += $1} END {printf "Total:%.0f\n", total}'
find . -type f -exec stat -c '%s' {} + |
awk '
{
total += $1
}
END {
printf "Total:%.0f\n", total
}
'
* %.0f
は、printf
が2147483647
(231-1)、%d
を書式指定子として使用すると、常に2147483647
として出力されます。 %.0f
の制限は、9007199254740992
(253)、これが懸念事項である場合(有益な情報をRotsorに感謝します)。
TL; DR:ls
およびawk
は、目的には不要です。分析するディレクトリでdu -cb
またはdu -bs
を使用します。
あなたの目的は
これらのすべてのアクションは、du
によって実行できます。
$ du -bs $HOME 2>/dev/null
76709521942 /home/xieerqi
du
には2つの「モード」があることに注意してください-サイズがどのくらいのファイルであるかを示すことができますORどれだけの実際のディスク容量(実際の、物理的な不動産)。すべてのファイルの合計サイズに関心があるため、見かけのファイルサイズが必要です。 -b
フラグはそれを正確に示します(-b
は--apparent-size --block-size=1
のエイリアスです)。
おそらく、より簡潔で適切な解決策は、du -bc
を目的のディレクトリで直接使用することです。たとえば、ホームディレクトリのサイズは約76 GBです
$ du -bc $HOME 2> /dev/null | tail -1
76694582570 total
何らかの理由で、フォルダーサイズとファイルサイズの違いを心配しています。コメントで次のように述べています。
ファイルサイズは一定であるのにディレクトリサイズが異なるため、私はlsを好むでしょう。
du
は再帰的で、ファイルサイズを合計します。また、ディレクトリの静的サイズは4096バイト(4k)ですが、du
を使用すると、du -bs directory_name
の結果に含まれます。このことを考慮:
$ du -b suse/openSUSE-Leap-42.1-DVD-x86_64.iso
4648337408 suse/openSUSE-Leap-42.1-DVD-x86_64.iso
$ du -b suse/
4648341504 suse/
$ bc <<< "4648337408+4096"
4648341504
$ mkdir suse/another_dir
$ du -b suse/another_dir
4096 suse/another_dir
$ du -bs suse/
4648345600 suse/
内部では、awk
はすべての計算を倍精度浮動小数点数を使用して実行します。デフォルトでは printf(3)
書式指定子%.6g
を使用して出力します。つまり、数値が6桁を超える場合は E-notation に切り替わります。見ました。これを回避するには、変数OFMT
を設定します。
ls -lR |
awk 'BEGIN { OFMT = "%d" }
/^-/ { total += $5 }
END { print "Total:", total }'
ただし、上限があり、それを超えるとできない正確なバイト数が得られません。合計の下位ビットの四捨五入を開始します。 500ギガバイト= 500 * 1024 * 1024 * 1024 = 536870912000≈239。通常のIEEE浮動小数点では、これはその制限を安全に下回ります(roughly252)。ただし、十分に大きいため、適切な「bignums」(サイズ無制限の整数)を備えたプログラミング言語を使用すると、個人的には気分が良くなります。たとえば、Python:
#! /usr/bin/python
import os
import sys
space = 0L # L means "long" - not necessary in Python 3
for subdir, dirs, files in os.walk(sys.argv[1]):
for f in files:
space += os.lstat(os.path.join(subdir, f)).st_size
sys.stdout.write("Total: {:d}\n".format(space))
これは、名前に異常な文字が含まれるファイルの問題の影響もまったく受けません。また、隠しファイルによって消費されるスペースをカウントします。
これにより、各ファイルで見えるバイト数が計算されます。これは、ls -l
が出力するものと同じです。代わりに実際にディスクで占有されているバイト数(du
が出力するもの)が必要な場合は、.st_size
を.st_blocks * 512
に置き換えます。 (はい、st_blksize
が異なる数値であっても、乗数は常に512です。)
ここに表示されるのは、大きな数字を表示する方法です。例えば:
1.23e+3 = 1.23*10^3 = 1230
私の知る限り、これをオフにすることはできませんが、質問で書いたように、du
の動作は異なるため、これを使用することをお勧めします。それ以外の場合は、数値を変換する必要があります。