bashスクリプトでファイルのサイズを取得するにはどうすればよいですか?
これを後で使用できるようにbash変数に割り当てるにはどうすればよいですか?
pv
とcat
進捗状況とETAを:)示しcopyコマンドの
bashスクリプトでファイルのサイズを取得するにはどうすればよいですか?
これを後で使用できるようにbash変数に割り当てるにはどうすればよいですか?
pv
とcat
進捗状況とETAを:)示しcopyコマンドの
回答:
GNUシステム上での最善策:
stat --printf="%s" file.any
man statから:
%s合計サイズ(バイト単位)
bashスクリプトで:
#!/bin/bash
FILENAME=/home/heiko/dummy/packages.txt
FILESIZE=$(stat -c%s "$FILENAME")
echo "Size of $FILENAME = $FILESIZE bytes."
注:Mac OS Xの端末でstatを使用する方法については、@ chbrownの回答を参照してください。
stat: illegal option -- c
stat --printf="%s" file.txt
Debian Jessieで何も出力しません
stat -f%z myfile.tar
man stat
--printfは末尾の改行を省略します。--format
または-c
を使用して出力を表示します。比較することによって、より多くの洞察を得るstat --printf="%s" file.any | xxd -
にstat -c "%s" file.any | xxd -
file_size_kb=`du -k "$filename" | cut -f1`
使用に関する問題stat
は、それがGNU(Linux)拡張機能であることです。 du -k
そしてcut -f1
POSIXによって指定されたため、任意のUnixシステムに移植されています。
たとえば、Solarisにはbashが付属していstat
ますが、bashは付属していません。したがって、これは完全に仮説ではありません。
ls
出力の正確な形式が指定されていないという点で同様の問題があります。そのため、出力の解析は移植性のある方法で実行できません。 du -h
GNU拡張機能でもあります。
可能な場合は携帯用構造物に固執すると、将来誰かの生活が楽になります。たぶんあなた自身。
du
ファイルのサイズを示すのではなく、ファイルが使用するスペースの量を示します。これは微妙に異なります(通常、レポートされるdu
サイズは、ファイルのサイズを最も近いブロック数に切り上げたものです。通常は512Bまたは1kBまたは4kBです)。
--bytes
またはの-b
代わりに-k
、受け入れられる回答である必要があります。
-h
(「人間」)オプションはdu
、一般的な場合に最も適切な回答を生成しfile_size=`du -h "$filename" | cut -f1
ます。K(キロバイト)、M(メガバイト)、またはG(ギガバイト)を適宜表示するためです。
「単語数」コマンド(wc
)を使用することもできます。
wc -c "$filename" | awk '{print $1}'
問題wc
は、ファイル名を追加し、出力をインデントすることです。例えば:
$ wc -c somefile.txt
1160 somefile.txt
ファイルサイズカウントを取得するためだけに完全なインタプリタ言語またはストリームエディタのチェーンを避けたい場合は、ファイルから入力をリダイレクトしwc
て、ファイル名が表示されないようにします。
wc -c < "$filename"
この最後の形式をコマンド置換で使用すると、シェル変数として探していた値を簡単に取得できます(以下のGillesで説明)。
size="$(wc -c <"$filename")"
wc -c <"$FILENAME"
したがって、他のクラフトのないサイズが得られsize=$(wc -c <"$FILENAME")
ます。
wc -c < file
少なくともOS Xでテストしたところ、非常に高速であるようです。wcには、-cのみを指定した場合にファイルを統計しようとする頭脳があると推測しています。
wc -c
はを使用fstat
しますが、ファイルの最後から2番目のブロックをシークし、最後の最大st_blksize
バイトを読み取ります。どうやらこれは、Linuxのファイルであるためである/proc
と/sys
例えばだけ近似しているのstatサイズを有し、かつwc
実際のサイズではなく、STAT-報告されたサイズを報告することを望んでいます。wc -c
以外のサイズを報告するのは奇妙だと思いwc
ますが、通常のディスクファイルであり、メモリにない場合は、ファイルからデータを読み取ることは考えられません。それとも悪いことに、ニアラインテープストレージ...
printf
インデントがまだ残っているようです(例:printf "Size: $size"
->)size: <4 spaces> 54339
。一方echo
、空白は無視されます。一貫性を保つ方法はありますか?
fstat
。実行strace wc -c </etc/passwd
してみて、それが何をしているかを見ることができます。
サイズの意味に依存します。
size=$(wc -c < "$file")
ファイルから読み取ることができるバイト数を提供します。IOW、それはファイルのコンテンツのサイズです。ただし、ファイルの内容を読み取ります(ほとんどのwc
実装では、ファイルが最適化として通常ファイルまたは通常ファイルへのシンボリックリンクである場合を除きます)。それには副作用があるかもしれません。たとえば、名前付きパイプのために、何を読んでてきたことは、もはや再び読み込むことができず、のようなもののため/dev/zero
か、/dev/random
無限の大きさであり、しばらく時間がかかるだろう。またread
、ファイルへのアクセス許可と最後のアクセスタイムスタンプが必要であることも意味しますが更新される可能性があります。
これは標準で移植可能ですが、一部のwc
実装ではその出力に先頭の空白が含まれることがあることに注意してください。それらを取り除く1つの方法は以下を使用することです:
size=$(($(wc -c < "$file")))
または内空の算術式に関するエラーを回避するdash
か、yash
ときwc
(ファイルを開くことができないときのように)出力を生成しません。
size=$(($(wc -c < "$file") +0))
ksh93
がwc
組み込まれているので(有効にする場合はとして呼び出すこともできcommand /opt/ast/bin/wc
ます)、そのシェル内の通常のファイルに対して最も効率的になります。
さまざまなシステムにはstat
、stat()
またはlstat()
システムコールへのインターフェイスと呼ばれるコマンドがあります。
iノードで見つかったこれらのレポート情報。その情報の1つがst_size
属性です。通常のファイルの場合、それはコンテンツのサイズです(エラーがない場合にそこから読み取ることができるデータの量(ほとんどのwc -c
実装が最適化で使用するものです))。シンボリックリンクの場合、それはターゲットパスのバイト単位のサイズです。名前付きパイプの場合、システムに応じて、0またはパイプバッファーに現在あるバイト数のいずれかです。システムに応じて、0または基礎となるストレージのバイト単位のサイズを取得するブロックデバイスについても同じです。
その情報を取得するためにファイルの読み取り権限は必要ありません。リンク先のディレクトリに対する検索権限のみが必要です。
時系列順に、以下があります。
IRIXstat
(90年代):
stat -qLs -- "$file"
()または次のst_size
属性を返します:$file
lstat()
stat -s -- "$file"
$file
シンボリックリンクの場合を除き、シンボリックst_size
リンク解決後のファイルの場合と同じです。
zsh
stat
モジュールに組み込まれた(現在はとしても知られzstat
ていzsh/stat
ます)(ロード済みzmodload zsh/stat
)(1997):
stat -L +size -- $file # st_size of file
stat +size -- $file # after symlink resolution
または変数に保存するには:
stat -L -A size +size -- $file
明らかに、それはそのシェルで最も効率的です。
GNUstat
(2001); stat
2005年からBusyBoxでも(GNUからコピーstat
):
stat -c %s -- "$file" # st_size of file
stat -Lc %s -- "$file" # after symlink resolution
(-L
IRIXまたはに比べての意味が逆になっていることに注意してくださいzsh
stat
。
BSDstat
(2002):
stat -f %z -- "$file" # st_size of file
stat -Lf %z -- "$file" # after symlink resolution
または、次のようなスクリプト言語のstat()
/ lstat()
関数を使用できますperl
。
perl -le 'print((lstat shift)[7])' -- "$file"
AIXには、すべての(シンボリックリンクでは機能しないため)情報をすべてダンプするistat
コマンドがあり、次のように後処理できます。stat()
lstat()
LC_ALL=C istat "$file" | awk 'NR == 4 {print $5}'
(詳細を理解するのに役立つ @JeffSchallerに感謝します)。
でtcsh
:
@ size = -Z $file:q
(シンボリックリンク解決後のサイズ)
GNUがそのstat
コマンドを導入するずっと前にfind
、その-printf
述語(すでに1991年)を使用してGNU コマンドで同じことが達成できました。
find -- "$file" -prune -printf '%s\n' # st_size of file
find -L -- "$file" -prune -printf '%s\n' # after symlink resolution
一つの問題はしかし場合には動作しないです$file
から始まる-
かであるfind
述語を(のような!
、(
...)。
stat()
/ lstat()
情報を取得する標準コマンドはls
です。
POSIXly、次のことができます:
LC_ALL=C ls -dn -- "$file" | awk '{print $5; exit}'
-L
シンボリックリンクの解決後に同じものを追加します。5 番目のフィールドはサイズではなくデバイスのメジャー番号ですが、デバイスファイルでは機能しません。
ブロックデバイスの場合、stat()
に0を返すシステムにはst_size
通常、ブロックデバイスのサイズを報告する他のAPIがあります。たとえば、LinuxにはがありBLKGETSIZE64
ioctl()
、ほとんどのLinuxディストリビューションにはblockdev
、それを利用できるコマンドが付属しています。
blockdev --getsize64 -- "$device_file"
ただし、そのためにはデバイスファイルの読み取り権限が必要です。通常、他の方法でサイズを導出することが可能です。たとえば(Linuxでも):
lsblk -bdno size -- "$device_file"
空のデバイスを除いて動作するはずです。
すべてのシーク可能なファイル(通常のファイル、ほとんどのブロックデバイス、一部のキャラクターデバイスを含む)で機能するアプローチは、ファイルを開いて最後までシークすることです。
ありzsh
(zsh/system
モジュールのロード後):
{sysseek -w end 0 && size=$((systell(0)))} < $file
でksh93
:
< "$file" <#((size=EOF))
または
{ size=$(<#((EOF))); } < "$file"
でperl
:
perl -le 'seek STDIN, 0, 2 or die "seek: $!"; print tell STDIN' < "$file"
名前付きパイプのために、我々はいくつかのシステム(少なくともAIX、Solaris版、HP / UX)はパイプバッファ内のデータ量を利用可能にすることを見てきましたstat()
s「をst_size
。一部の(LinuxやFreeBSDなど)しません。
少なくともLinuxではFIONREAD
ioctl()
、パイプを開いた後に使用できます(ハングしないように、読み取り+書き込みモードで)。
fuser -s -- "$fifo_file" &&
perl -le 'require "sys/ioctl.ph";
ioctl(STDIN, &FIONREAD, $n) or die$!;
print unpack "L", $n' <> "$fifo_file"
ただし、パイプの内容は読み取れませんが、ここで名前付きパイプを開くだけでは副作用が発生する可能性があることに注意してください。私たちは、使用しているfuser
最初のいくつかのプロセスがすでにそれを軽減するためのオープンパイプを持っていることを確認することではなくて、それは誰にでもありませんfuser
すべてのプロセスをチェックすることができないかもしれません。
さて、これまでのところ、ファイルに関連付けられているプライマリデータのサイズのみを考慮してきました。メタデータのサイズと、そのファイルを保存するために必要なすべてのサポートインフラストラクチャは考慮されません。
によって返される別のiノード属性はstat()
ですst_blocks
。これは、ファイルのデータ(および場合によってはLinuxのext4ファイルシステムの拡張属性などの一部のメタデータ)を格納するために使用される512バイトブロックの数です。iノード自体や、ファイルがリンクされているディレクトリのエントリは含まれません。
サイズとディスク使用量は、圧縮、スパース性(一部のメタデータ)、一部のファイルシステムの間接ブロックなどの余分なインフラストラクチャが後者に影響を与えるため、必ずしも密接に関連しているわけではありません。
これは通常、du
ディスク使用量のレポートに使用されます。上記のコマンドのほとんどは、その情報を取得できます。
POSIXLY_CORRECT=1 ls -sd -- "$file" | awk '{print $1; exit}'
POSIXLY_CORRECT=1 du -s -- "$file"
(ファイル内のファイルのディスク使用量を含むディレクトリ用ではありません)。find -- "$file" -printf '%b\n'
zstat -L +block -- $file
stat -c %b -- "$file"
stat -f %b -- "$file"
perl -le 'print((lstat shift)[12])' -- "$file"
wc -c
はを使用しfstat
ますが、最後の最新st_blksize
バイトを読み取ります。どうやら、Linuxのファイルであるため、これはある/proc
と/sys
例えばのみ概算でありSTATサイズを有します。これは正確さには適していますが、ファイルの終わりがメモリ上ではなくディスク上にある場合(特に、ループ内の多くのファイルで使用される場合)には不適切です。また、ファイルをニアラインテープストレージに移行した場合、またはFUSEの透過的解凍ファイルシステムなどに移行した場合は非常に悪いです。
ls -go file | awk '{print $3}'
-go
はSysVのものであり、BSDでは動作しません(POSIXのオプション(XSI))。また、必要になりますls -god file | awk '{print $3; exit}'
(-d
ディレクトリで動作するexit
ため、ターゲットに改行があるシンボリックリンクのため)。デバイスファイルの問題も残ります。
wc -c
、バイト数を報告するものではないことは明らかです。
このスクリプトは、ファイルサイズを計算する多くの方法を組み合わせています。
(
du --apparent-size --block-size=1 "$file" 2>/dev/null ||
gdu --apparent-size --block-size=1 "$file" 2>/dev/null ||
find "$file" -printf "%s" 2>/dev/null ||
gfind "$file" -printf "%s" 2>/dev/null ||
stat --printf="%s" "$file" 2>/dev/null ||
stat -f%z "$file" 2>/dev/null ||
wc -c <"$file" 2>/dev/null
) | awk '{print $1}'
このスクリプトは、Linux、BSD、OSX、Solaris、SunOSなどを含む多くのUnixシステムで動作します。
ファイルサイズはバイト数を示します。これは見かけのサイズです。これは、ファイルが通常のディスクで使用するバイト数で、特別な圧縮、特別なスパース領域、未割り当てブロックなどはありません。
このスクリプトには、より多くのヘルプとオプションが含まれる製品版があります:https : //github.com/SixArm/file-size
statは、最も少ないシステムコールでこれを行うようです。
$ set debian-live-8.2.0-amd64-xfce-desktop.iso
$ strace stat --format %s $1 | wc
282 2795 27364
$ strace wc --bytes $1 | wc
307 3063 29091
$ strace du --bytes $1 | wc
437 4376 41955
$ strace find $1 -printf %s | wc
604 6061 64793
ls -l filename
ファイルサイズ、アクセス許可、所有者など、ファイルに関する多くの情報を提供します。
5列目のファイルサイズ。バイト単位で表示されます。以下の例では、ファイルサイズは2 KB未満です。
-rw-r--r-- 1 user owner 1985 2011-07-12 16:48 index.php
編集:これは明らかにstat
コマンドほど信頼性が高くありません。
ls -l
とstat
コマンドが信頼できるサイズ情報を提供すると思います。私はそれとは逆の言及を見つけませんでした。ls -s
ブロック数でサイズを指定します。
du filename
ディスク使用量をバイト単位で通知します。
私du -h filename
は、人間が読める形式でサイズを提供することを好みます。
du
、単純なバイト数ではなく、1024バイトのブロック単位でサイズを出力します。
du
は、512バイト単位の数で出力されることに注意してください。GNU du
はPOSIXLY_CORRECT
、その環境で呼び出されない限り、代わりにkibibytesを使用します。
シェルスクリプトに委任できる小さなユーティリティ関数を作成します。
例
#! /bin/sh -
# vim: set ft=sh
# size utility that works on GNU and BSD systems
size(){
case $(uname) in
(Darwin | *BSD*)
stat -Lf %z -- "$1";;
(*) stat -c %s -- "$1"
esac
}
for f do
printf '%s\n' "$f : $(gzip < "$f" | wc -c) bytes (versus $(size "$f") bytes)"
done
@StéphaneChazelasの回答からの情報に基づいています。
gzip -v < file > /dev/null
ファイルの圧縮率の確認も参照してください。
case
ステートメントを使用したい典型的なケースです。case
パターンマッチングを行うBourne / POSIXコンストラクトです。[[...]]
ksh / bash / zshのみです(バリエーションあり)。
AWK 1ライナーを見つけ、バグがありましたが、修正しました。また、TeraBytesの後にPetaBytesを追加しました。
FILE_SIZE=234234 # FILESIZE IN BYTES
FILE_SIZE=$(echo "${FILE_SIZE}" | awk '{ split( "B KB MB GB TB PB" , v ); s=1; while( $1>1024 ){ $1/=1024; s++ } printf "%.2f %s", $1, v[s] }')
statがすべての単一のシステムにあるとは限らないことを考慮すると、ほとんど常にAWKソリューションを使用できます。例; Raspberry Piにはstatはありませんが、awkがあります。
もう一つのPOSIX準拠した方法は、使用することですawk
そのにlength()
改行文字を除いて、入力ファイルの各行に文字で、長さを返す関数。そうすることで
awk '{ sum+=length } END { print sum+NR }' file
にがNR
追加されていることを確認sum
します。これにより、ファイルで遭遇する文字の総数と改行の総数が得られます。length()
関数はawk
、デフォルトの手段によって引きとりlength($0)
、現在の行全体のためです。
printf 'a\nb' | awk '{ sum+=length } END { print sum+NR }'
3が、印刷物4を印刷する必要があります
私は自分でwcオプションが好きです。「bc」と組み合わせると、必要な数だけ小数を取得できます。
「ls -alh」コマンドの「ファイルサイズ」列をわかりやすくするスクリプトを改善しようとしていました。整数のファイルサイズだけが欲しくなく、小数点以下2桁が適しているように思えたので、この説明を読んだ後、以下のコードを思い付きました。
スクリプトにこれを含める場合は、セミコロンで改行することをお勧めします。
file=$1; string=$(wc -c $file); bite=${string% *}; okay=$(echo "scale=2; $bite/1024" | bc);friend=$(echo -e "$file $okay" "kb"); echo -e "$friend"
私のスクリプトは、「画像ファイルの長さを取得する」ためのgpflと呼ばれます。imagemagickでファイルをmogrifyした後、GUI jpegビューアーで画像を開いたり再読み込みする前に使用します。
既に提供され、議論されているものから多くを借りているため、これが「答え」としてどのように評価されるのかわかりません。それで私はそこに置いておきます。
BZT
wc
はファイルの最後のブロックを読み取ることに注意してくださいstat.st_size
(Linux /proc
や/sys
ファイルの場合など)。私は、彼らが数行をそのロジックを下に追加したときに、メインのコメントはより複雑にしないことを決定した推測:lingrok.org/xref/coreutils/src/wc.c#246
最も速くて簡単な(IMO)方法は次のとおりです。
bash_var=$(stat -c %s /path/to/filename)
du
及びwc
免責条項が持つべき答えTHISを決してしない実際の生活の中で。今夜、実生活のアプリケーションで自分の答えを使ってみたところ、共有する価値があると思いました。私たちは皆意見が肩をすくめていると思います。