web-dev-qa-db-ja.com

stdinのサイズを取得するにはどうすればよいですか?

大きなディレクトリを圧縮しようとしていますが、結果のファイルのサイズを正確に知りたいです。

私はduを使ってみました:

$ tar -cv dir | du -h -
du: cannot access '-': No such file or directory

次に、「-」のファイルバージョンを使用してみました。

$ tar -cv dir | du -h /dev/stdin
1.0K

この数値は正確ではないと確信しています。 stdinのサイズを取得するにはどうすればよいですか?

8
strugee

tl; drtar -cv dir | wc -c - | cut -d' ' -f 1 | awk '{print $1/1000"K"}'

duは、実際にはファイル自体のサイズをカウントしません。カーネルにファイルシステムのクエリを要求するだけで、ファイルシステムはすでにファイルサイズを追跡しています。これがとても速い理由です。そのため、ファイルではなくストリームをカウントしているため、duは機能しません。私の推測では、1.0Kはカーネルの/dev/std*のハードコードされたサイズです。

解決策は、カーネルをクエリする代わりにバイト自体をカウントするwc -cを使用することです。

$ tar -cv dir | wc -c

du -hのような出力が必要な場合:

$ tar -cv dir | wc -c | awk '{print $1/1000"K"}'

awkは、数値を人間が読める結果に変換します。

10
strugee

GNU tarを使用すると、次のことができます。

tar --totals -c . >/dev/null

...出力は次のようになります...

Total bytes written: 5990400 (5.8MiB, 5.5GiB/s)

... stderr上。同様に、任意のtar(またはストリーム)を使用すると、ddを使用してバイトカウントに関するレポートを配信できます。これはwcよりも好ましい場合とそうでない場合がありますが、ddのデフォルトは512バイトのブロックサイズで、これはtarのブロックサイズと同じです。システムの PIPE_BUF が十分に大きければ、ddのブロックサイズを拡張してtarのレコードサイズ-20ブロック、つまり10240バイト。このような:

tar -c . | dd bs=bx20 >/dev/null
585+0 records in
585+0 records out
5990400 bytes (6.0 MB) copied, 0.0085661 s, 699 MB/s

これはwcよりも優れたソリューションを提供する場合と提供しない場合があります。

ただし、ddtarの両方のユースケースで、実際にストリームを破棄する必要はありません。上記の/dev/nullにリダイレクトしますが、一部のファイルに簡単にリダイレクトでき、作成時のサイズに関するレポートを引き続き受信できます。

6
mikeserv

私はお勧めします:

tar cf - dir | wc -c

単純なc(先頭に-は不要)を使用してtarアーカイブを作成し、fは出力ファイルを指定し、-stdoutになります。 (サイズだけが必要で、その下に多くのファイルがある場合dirパフォーマンス上の理由から、tarvを省略してもかまいません。)

5
Janis

質問の文言はtar ... | wc -c上記の回答。私はもともと、tarファイルの作成中にサイズを報告してほしい(おそらくtarの出力がネットワークリンク経由でパイプ処理されていたのではないか?).

その場合は、pv-パイプビューアをお勧めします。私はそれへの言及を見ましたが、まだそれを試す機会がありませんでした。

参照

1
Jeff Schaller