bashスクリプトでファイルのサイズを取得するにはどうすればよいですか?
これをbash変数に割り当てて、後で使用できるようにするにはどうすればよいですか?
コメント
回答
GNUシステムの場合の最善の策:
stat --printf="%s" file.any
%s合計サイズ(バイト単位)
bashスクリプトの場合:
#!/bin/bash FILENAME=/home/heiko/dummy/packages.txt FILESIZE=$(stat -c%s "$FILENAME") echo "Size of $FILENAME = $FILESIZE bytes."
注:
@chbrownの回答。
コメント
- @ haunted85
statは、’ LinuxまたはCygwin(は’標準ではありません)。wc -cas Eugが提案é ne は移植可能です。 -
stat: illegal option -- c -
stat --printf="%s" file.txtは’ t DebianJessieで何でも出力します… - MacOSではこれは機能します:
stat -f%z myfile.tar - @woohooプロンプトが出力を上書きします。
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には付属していません。 。したがって、これは完全に架空のものではありません。
lsにも同様の問題があり、出力の正確な形式が指定されていないため、出力の解析を移植可能に行うことができません。 。 du -hもGNU拡張機能です。
可能な場合は移植可能な構造に固執してください。そうすれば、将来誰かの生活が楽になります。たぶんあなた自身のものでしょう。
コメント
-
duは’を提供しませんファイルのサイズは、ファイルが使用するスペースの量を示します。これは微妙に異なります(通常、duによって報告されるサイズは、最も近いものに切り上げられたファイルのサイズです。ブロックの数。ブロックは通常512Bまたは1kBまたは4kBです。 - @Gilles、スパースファイル(つまり、穴のあるファイル)は長さよりも短いと報告します。
- これは、
-kの代わりに--bytesまたは-bを使用することで受け入れられるはずです。 - @fralau:OPは、後で使用できるように、これをbash変数に”割り当てたいと考えています”、だから彼らはアクチュを欲しがる可能性がはるかに高い人間が読める近似値ではなく、すべての数値。また、
-hはGNU拡張機能です。 標準 - duを
--apparent-sizeフラグとともに使用するとより多くの情報が返されます正確なサイズ(男性に記載されているとおり:print apparent sizes, rather than disk usage; although the apparent size is usually smaller, it may be larger due to holes in ('sparse') files, internal fragmentation, indirect blocks, and the like)
回答
「wordcount」コマンド(wc)を使用することもできます:
wc -c "$filename" | awk "{print $1}"
wcの問題は、ファイル名を追加して出力をインデントすることです。例:
$ wc -c somefile.txt 1160 somefile.txt
ファイルサイズカウントを取得するためだけに完全に解釈された言語またはストリームエディタをチェーンすることを避けたい場合は、ファイルからの入力をリダイレクトして、wcがファイル名を認識しないようにします。
wc -c < "$filename"
size="$(wc -c <"$filename")"
コメント
-
wc -c <"$FILENAME"は、他のがらくたがないサイズを示します。したがって、size=$(wc -c <"$FILENAME")です。 - もう1つポイント:テストしたところ、
wc -c < fileは、少なくともOSXでは非常に高速なようです。I’ -cのみが指定されている場合、wcにはファイルの統計を試みる頭脳があると推測します。 - @EdwardFalk:GNU
wc -cはが、ファイルの最後から2番目のブロックを探し、最後の最大
st_blksizeバイトを読み取ります。どうやらこれは、Linux ‘の/procとの統計サイズは概算であり、wcは、統計で報告されたサイズではなく、実際のサイズを報告したいと考えています。wc -cがwcとは異なるサイズを報告するのは奇妙だと思いますが、’ ‘通常のディスクファイルであり、’がメモリにない場合、div>はファイルからデータを読み取ることを考えていません。さらに悪いことに、ニアラインテープストレージ… -
printfにはまだインデントが表示されているようです。printf "Size: $size"->size: <4 spaces> 54339。一方、echoは空白を無視します。一貫性を保つ方法はありますか? - @keithpjolley:
fstatを呼び出します。strace wc -c </etc/passwdを実行してみると、その動作を確認できます。
回答
BSD “s(macOS” s)statには、異なるフォーマット引数フラグと異なるフィールド指定子があります。 man stat(1)から:
-
-f format:指定された形式を使用して情報を表示します。有効なフォーマットの説明については、「フォーマット」セクションを参照してください。 - …「フォーマット」セクション…
-
z:のサイズファイルはバイト単位です。
今すぐまとめて:
stat -f%z myfile1.txt
コマンドを使用する方法についての @ b01の回答。:)
コメント
- これはBSDのみのソリューションであることに注意してください。’ GNU
stat、残念ながら。
回答
サイズの意味によって異なります。
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が組み込まれています(有効にしている場合は、呼び出すこともできます) as command /opt/ast/bin/wc)これにより、そのシェル内の通常のファイルに対して最も効率的になります。
さまざまなシステムにstatというコマンドがあります。 stat()またはlstat()システムコールへのインターフェースであるdiv>。
これらのレポート情報はiノード。その情報の1つは、st_size属性です。通常のファイルの場合、それはコンテンツのサイズです(エラーがない場合にコンテンツから読み取ることができるデータの量(ほとんどのwc -c実装が最適化で使用するもの) )。シンボリックリンクの場合、これはターゲットパスのバイト単位のサイズです。名前付きパイプの場合、システムに応じて、0または現在パイプバッファにあるバイト数のいずれかです。システムに応じて、基になるストレージの0またはバイト単位のサイズを取得するブロックデバイスについても同じです。
その情報を取得するためにファイルへの読み取り権限は必要ありません。検索権限のみが必要です。リンク先のディレクトリ。
時系列で、次のようになります。
-
IRIX
stat(90 “s):stat -qLs -- "$file"ividの
st_size属性を返します= “b8ccb6d7c5”>
(lstat())または:
stat -s -- "$file"
st_sizeです。
zsh stat組み込み(現在は
)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
明らかに、これが最も効率的です。そのシェル。
GNU stat (2001); BusyBox statでも2以降005(GNU statからコピー):
stat -c %s -- "$file" # st_size of file stat -Lc %s -- "$file" # after symlink resolution
(は、IRIXまたはzsh statとは逆になっています。
BSD stat (2002):
stat -f %z -- "$file" # st_size of file stat -Lf %z -- "$file" # after symlink resolution
または、iv id =などのスクリプト言語のstat() / lstat()関数を使用できます。 “ddc46a7499”> :
perl -le "print((lstat shift)[7])" -- "$file"
AIXには コマンドはすべてのstat()をダンプします(lstat()ではないため、シンボリックリンクでは機能しません)情報と後処理が可能です。例:
LC_ALL=C istat "$file" | awk "NR == 4 {print $5}"
tcshの場合:
@ size = -Z $file:q
(シンボリックリンク解決後のサイズ)
GNUがstatコマンドを導入するずっと前に、GNU findコマンドとその-printf述語(すでに1991年):
find -- "$file" -prune -printf "%s\n" # st_size of file find -L -- "$file" -prune -printf "%s\n" # after symlink resolution
1つの問題はそうではないということです$fileが-で始まる場合、またはfind述語(!、( …)。
stat() / lstat()の情報はlsです。
次のことができます:
LC_ALL=C ls -dn -- "$file" | awk "{print $5; exit}"
シンボリックリンクの解決後に同じように-Lを追加します。 5 th フィールドがサイズではなくデバイスのメジャー番号である場合でも、これはデバイスファイルでは機能しません。
ブロックデバイスの場合、stat()はst_sizeに対して0を返します。通常、ブロックデバイスのサイズを報告する他のAPIがあります。たとえば、LinuxにはBLKGETSIZE64 ioctl()、およびほとんどのLinuxディストリビューションには、これを利用できるblockdevコマンドが付属しています。
blockdev --getsize64 -- "$device_file"
ただし、そのためにはデバイスファイルへの読み取り権限が必要です。通常、他の方法でサイズを導出することは可能です。たとえば(まだLinux上):
lsblk -bdno size -- "$device_file"
空のデバイスを除いて機能するはずです。
すべてので機能するアプローチシーク可能なファイル(通常のファイル、ほとんどのブロックデバイス、一部のキャラクターデバイスを含む)は、ファイルを開いて最後までシークすることです。
-
(
zsh/systemモジュールをロードした後):{sysseek -w end 0 && size=$((systell(0)))} < $file -
ksh93の場合:< "$file" <#((size=EOF))または
{ size=$(<#((EOF))); } < "$file" -
with
perl:perl -le "seek STDIN, 0, 2 or die "seek: $!"; print tell STDIN" < "$file"
名前付きパイプの場合、一部のシステム(少なくとも、AIX、Solaris、HP / UX)では、パイプバッファー内のデータ量をstat()で使用できるようになっています。 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"
ただし、読み取り / em>パイプの内容、ここで名前付きパイプを開くだけでも、副作用が発生する可能性があります。 fuserを使用して、それを軽減するために一部のプロセスですでにパイプが開いていることを最初に確認しますが、fuserのように絶対確実ではありません。すべてのプロセスをチェックすることはできません。
これまでのところ、ファイルに関連付けられているプライマリデータのサイズのみを検討してきました。これは、メタデータのサイズと、そのファイルを保存するために必要なすべてのサポートインフラストラクチャを考慮していません。
stat()によって返される別のiノード属性は
。これは、ファイルのデータ(および、Linuxのext4ファイルシステムの拡張属性などのメタデータの一部)を格納するために使用される512バイトブロックの数です。 「iノード自体、またはファイルがリンクされているディレクトリ内のエントリを含めないでください。
サイズとディスク使用量は、圧縮、まばらさ(メタデータの場合もある)、間接ブロックなどの追加のインフラストラクチャとして必ずしも密接に関連しているわけではありません。一部のファイルシステムでは、後者に影響を与えます。
これは通常、duがディスク使用量を報告するために使用するものです。上記のコマンドのほとんどは次のことができます。その情報を入手してください。
-
POSIXLY_CORRECT=1 ls -sd -- "$file" | awk "{print $1; exit}" -
POSIXLY_CORRECT=1 du -s -- "$file"(ディレクトリ用ではありませんこれにはディスクの使用が含まれます内のファイルのe)。 - GNU
find -- "$file" -printf "%b\n" -
zstat -L +block -- $file - GNU
stat -c %b -- "$file" - BSD
stat -f %b -- "$file" -
perl -le "print((lstat shift)[12])" -- "$file"
コメント
- 明らかに最も包括的で情報的な回答。ありがとうございました。これを使用して、BSDおよびGNU統計情報を使用してクロスプラットフォームのbashスクリプトを作成できます
- おもしろい事実:GNU coreutils
wc -cはfstatですが、最後の最大st_blksizeバイトを読み取ります。どうやらこれは、Linux ‘の/procとの統計サイズは概算です。これは正確さには役立ちますが、ファイルの終わりがメモリではなくディスク上にある場合(特に、ループ内の多くのファイルで使用される場合)は良くありません。また、ファイルがニアラインテープストレージに移行された場合、またはたとえばFUSE透過解凍ファイルシステム。 - これも機能しません
ls -go file | awk '{print $3}' - @StevenPennyそれらの
-goはSysVのものであり、’ BSDでは機能しません(POSIXではオプション(XSI))。 ‘ディレクトリで機能するには、ls -god file | awk '{print $3; exit}'(-dも必要です。)。デバイスファイルの問題も残っています。
- @αғsнιηUnixAPIは、テキストファイルとバイナリファイルを区別しません。 ‘はすべてのバイトシーケンスです。一部のアプリケーションでは、これらのバイトをテキストとして解釈したいが、バイト数を報告する
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}"
このスクリプトは多くのUnixシステムで機能しますLinux、BSD、OSX、Solaris、SunOSなどを含みます。
ファイルサイズはバイト数を示します。これは見かけのサイズであり、ファイルが通常のディスクで使用するバイト数であり、特別な圧縮、特別なスパース領域、または未割り当てのブロックなどはありません。
このスクリプトには、より多くのヘルプとその他のオプション: 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列目のファイルサイズで、バイト単位で表示されます。以下の例では、ファイルサイズは2KBをわずかに下回っています:
-rw-r--r-- 1 user owner 1985 2011-07-12 16:48 index.php
編集:これは明らかにstatコマンドほど信頼性がありません。
コメント
-
ls -lコマンドとstatコマンドの両方で信頼できるサイズ情報が得られると思います。反対の言及は見つかりませんでした。ls -sはブロック数でサイズを示します。 - @ dabest1 it ‘は信頼性が低いという意味で別のUNIXでは、出力が異なる場合があります(一部のUNIXでは異なります)。
- はい、IIRC、Solarisはデフォルトでグループ名を表示しませんでした’、出力の列が少なくなります。
- サイズは空白で囲まれた純粋な数値であり、日付年は定義された形式の純粋な数値であるため、正規表現を使用してユーザーを処理することができます。 +グループが存在するかどうかに関係なく、1つのフィールドとしての所有者。 (読者のための演習!)
回答
du filenameディスク使用量をバイト単位で示します。
du -h filenameが好きです。これにより、人間が読める形式でサイズが表示されます。
コメント
- thatまたは
stat -c "%s";) - このフレーバーの
duは、サイズを次のブロックで出力します。単純なバイト数ではなく、1024バイト。 - 標準の
duは512バイト単位の出力を提供することに注意してください。 GNUduは、環境内でPOSIXLY_CORRECTを指定して呼び出されない限り、代わりにキビバイトを使用します。 - タイプディレクトリのファイルの場合、これはディレクトリのディスク使用量だけでなく、その中の他のすべてのファイルのディスク使用量も示します。
回答
委任できるシェルスクリプトに小さなユーティリティ関数を作成します。
例
#! /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も参照してください。 - @St é phaneChazelasは、それが改善されたと思うかどうかわかりません。これらのケースステートメントは簡単に初心者を先延ばしにする可能性があります。正しくする方法を覚えていません:-) 2つ以上のケースがある場合はポイントがわかりますが、それ以外の場合は… +
- ‘も好みの問題だと思います。ただし、ここでは’が’
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ソリューションを使用できます。例; RaspberryPiには stat はありませんが、 awk
。
コメント
- OPが求めたものではありませんが、ちょっとした作業です。
回答
私はwcオプションが好きです。 「bc」と組み合わせると、小数点以下の桁数を好きなだけ取得できます。
「ls-」の「ファイルサイズ」列をawkで削除したスクリプトを改善しようとしていました。 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 を実行した後、GUIjpegビューアで画像を開いたり再読み込みしたりする前に使用します。
これがどのように評価されるかわかりません。すでに提供され議論されているものから多くを借りているので、「答え」。だから私はそこに置いておきます。
BZT
コメント
- 使用したい” stat “または” ls “。通常、’ ” wc “を使用してファイルサイズを取得するのは好きではありません。ファイル全体を物理的に読み取ります。ファイルが多い場合、または特に大きなファイルがある場合は、時間がかかることがあります。ただし、ソリューションは創造的です… +1。
- 概念に同意します。 ” wc “ですが、” wc -c “を使用すると、データは読み取られません。代わりに、lseekが使用されます。ファイルのバイト数を計算します。 lingrok.org/xref/coreutils/src/wc.c#228
- @ bbaja42 :GNU Coreutils は、
stat.st_sizeが概算にすぎない場合(Linux/procのように)、ファイルの最後のブロックを読み取ります。および/sysファイル)。 lingrok.org/xref/coreutils/src/wc.c#246
回答
最速かつ最も単純な(IMO)メソッドは次のとおりです。
bash_var=$(stat -c %s /path/to/filename)
コメント
- 次に、statに言及している既存の回答の1つ以上に賛成します。もう一度繰り返す必要はありません…
- @JeffSchaller私はあなたの指示に対するStephane ‘の回答に賛成しました。私の目的には複雑すぎると思います。 だから私はこの簡単な答えを気の合う魂のために投稿しました。
- ありがとう。 ‘は、” stat ” 6番目のインスタンスです。 / div>回答は’このQ & Aを単純化するのではなく、新しい読者に”この回答は他の回答とどのように異なりますか?”そして、混乱を減らすのではなく、増やすことになります。
- @JeffSchallerだと思います。 しかし、免責事項が必要な多くの
duとwcの回答について文句を言うことができますこれは絶対にしないでください 生活。 今夜、実際のアプリケーションで自分の答えを使用したところ、共有する価値があると思いました。 私たちは皆、肩をすくめるという意見を持っていると思います。
pvおよびcatは、進行状況とETAを表示するコピーコマンドです:)-sなので、ファイルの長さがゼロ以外であるかどうかをif [ -s file ]; then echo "file has nonzero size" ; fi