Bashを使用してファイルのサイズを確認する方法


145

サイズ0をチェックするスクリプトを持っていますが、代わりにファイルサイズをチェックする簡単な方法があるはずだと思いました。すなわちfile.txt、通常、100Kです。スクリプトが90k(0を含む)より小さいかどうかを確認し、この場合ファイルが破損しているため、新しいコピーを作成する方法。

現在使用しているもの。

if [ -n file.txt ]
then
 echo "everything is good"
else
 mail -s "file.txt size is zero, please fix. " myemail@gmail.com < /dev/null
 # Grab wget as a fallback 
 wget -c https://www.server.org/file.txt -P /root/tmp --output-document=/root/tmp/file.txt
 mv -f /root/tmp/file.txt /var/www/file.txt
fi

回答:


250

[ -n file.txt ]サイズはチェックしません。文字列のfile.txt長さがゼロでないことをチェックするため、常に成功します。

「サイズがゼロ以外です」と言いたい場合は、が必要[ -s file.txt ]です。

ファイルのサイズwc -cを取得するには、サイズ(ファイル長)をバイト単位で取得するために使用できます。

file=file.txt
minimumsize=90000
actualsize=$(wc -c <"$file")
if [ $actualsize -ge $minimumsize ]; then
    echo size is over $minimumsize bytes
else
    echo size is under $minimumsize bytes
fi

この場合、それがあなたが望んでいるように思えます。

しかし参考までに、ファイルが使用しているディスク容量を知りたい場合はdu -k、サイズ(使用されているディスク容量)をキロバイト単位で取得できます。

file=file.txt
minimumsize=90
actualsize=$(du -k "$file" | cut -f 1)
if [ $actualsize -ge $minimumsize ]; then
    echo size is over $minimumsize kilobytes
else
    echo size is under $minimumsize kilobytes
fi

出力形式をより詳細に制御する必要がある場合は、もご覧くださいstat。Linuxでは、のようなものから始め、stat -c '%s' file.txtBSD / Mac OS Xではのようなものから始めますstat -f '%z' file.txt


5
なぜdu -b "$file" | cut -f 1代わりにstat -c '%s' "$file"?またはstat --printf="%s" "$file"
mivk

1
それはよりポータブルだからです。BSDとLinuxではstat フラグが異なります。
ミケル

1
... | cut -d' ' -f1Ubuntuで動作するように変更する必要がありました。
Mikepote 2014年

8
を使用しますwc -c < "$file"(に注意してください<)。その場合、| cut ...パーツは必要ありません(投稿されたとおり、OSXでは機能しません)。OSXでの最小BLOCKSIZEdu512です。
mklement0 2014年

3
@PetriSirkkala私のLinuxシステムでwc -c <filenamefstat、and も使用しseekますか?fstatはパス名ではなくfd を取ることに注意してください。
ミケル2017

24

statファイルのサイズをチェックすることについて誰も言及しなかったことに驚いています。いくつかの方法は間違いなく優れ-sています。ファイルが空であるかどうかを調べるのに他の方法よりも簡単です。そして、あなたがサイズのファイルを見つけたいなら、find確かに行く方法です。

またdu、ファイルサイズをkbで取得することも好きですが、バイトの場合は次のように使用しますstat

size=$(stat -f%z $filename) # BSD stat

size=$(stat -c%s $filename) # GNU stat?

2
stat素晴らしいアイデアですが、CentOSではこれが私にとってうまくいきました:size=$(stat -c%s $filename)
Oz Solomon

2
残念ながら、GNUとBSDの違いは、この代替策を少し魅力的にしないものです。:(
lapo

1
ファイルがスパースの場合、statは誤解を招く可能性があります。statによって報告されたブロックを使用して、使用されているスペースを計算できます。
Ajith Antony

@AjithAntonyそれは私には起こらなかった興味深い点です。状況statによっては正しいことがわかりますが、スパースファイルはほとんどの状況では関係ありませんが、すべてではありません。
ダニエルC.ソブラル

17

awkと二重括弧を使用した代替ソリューション:

FILENAME=file.txt
SIZE=$(du -sb $FILENAME | awk '{ print $1 }')

if ((SIZE<90000)) ; then 
    echo "less"; 
else 
    echo "not less"; 
fi

1
いいですが、がduサポートしていないOSXでは動作しません-b。(これは意識的なスタイルの選択肢かもしれませんが、ちょうど代替に言及する:あなたは、省略することができます$内の接頭辞を(( ... ))変数を参照するとき:((SIZE<90000))
mklement0

1
実際、それを省略するのは間違っていると思った以前のユーザーによる編集でした$
fstab

2
@fstab、(内部コマンド)awkを使用して省略できます:readbashread SIZE _ <<<$(du -sb "$FILENAME")
Jdamian '13

13

findこの構文を処理する場合は、それを使用できます。

find -maxdepth 1 -name "file.txt" -size -90k

これはfile.txt、サイズがfile.txt90k未満の場合にのみstdoutに出力されます。サイズが90k未満のscript場合にスクリプトを実行するにはfile.txt

find -maxdepth 1 -name "file.txt" -size -90k -exec script \;

3
+1ですが、OSXでも機能させるには、明示的なターゲットディレクトリ引数が必要です。例:find . -maxdepth 1 -name "file.txt" -size -90k
mklement0

8

ファイルのサイズだけを探している場合:

$ cat $file | wc -c
> 203233

1
これは実行可能な最短の回答かもしれませんが、おそらく最も遅いでしょう。:)
SunSparc 2014

2
はい、確かに経済的に優れています:エンジニアリング時間のコスト>計算時間のコスト
BananaNeil 2014

8
wc -c "$file"回答として2011年(3年前)に与えられました。はい、wc -c "$file"ファイル名と文字数を出力するという問題があるため、初期の回答では、文字数を分離するコマンドが追加されました。しかしwc -c < "$file"、それは追加除き、その修正される問題は、あなたの答えはと同等である月2014にコメントとして追加されました「の無駄な使用をcat。また、正当な理由がない限り、すべてのシェル変数参照を引用する必要があります。
G-Manは 'Reinstate Monica'

1
cat.if [$(head -c 90000 $ file | wc -c)-lt 90000]の代わりにhead -cを使用することで、これをより効率的にすることができます。次に、「ファイルが90kより小さい」とエコーします。fi。CentOSでテストされているため、BSDまたはOSXで動作する場合と動作しない場合があります。
Kevin Keane

@BananaNeil 20秒ごとにこのプロセスを実行して、ファイルサイズの増分を確認できるようにするにはどうすればよいですか?
2017年

6

これはlinuxとmacosの両方で機能します

function filesize
{
    local file=$1
    size=`stat -c%s $file 2>/dev/null` # linux
    if [ $? -eq 0 ]
    then
        echo $size
        return 0
    fi

    eval $(stat -s $file) # macos
    if [ $? -eq 0 ]
    then
        echo $st_size
        return 0
    fi

    return -1
}

5

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

私がそれを正しく理解している場合、テストはパイプリダイレクトでも行う必要がありますか?:strace du --bytes $1 2>&1 >/dev/null | wc その場合、ArchLinuxのamd64アーキテクチャ(通常はすべての最新バージョン)では、45行du、46行stat、47行wc、の72行find
VasiliNovikov

5
python -c 'import os; print (os.path.getsize("... filename ..."))'

移植可能な、Pythonのすべてのフレーバーは、stat方言の変動を回避します


4

LinuxとMac OS Xの両方(およびおそらく他のBSD)でファイルサイズを取得するためのオプションは多くなく、ここで提案されているオプションのほとんどは1つのシステムでのみ機能します。

与えられたf=/path/to/your/file

LinuxとMac両方のBashで機能するもの:

size=$( perl -e 'print -s shift' "$f" )

または

size=$( wc -c "$f" | awk '{print $1}' )

他の回答はLinuxでは正常に機能しますが、Macでは機能しません。

  • du 持っていない -bMacにオプション、BLOCKSIZE = 1のトリックは機能しません(「最小ブロックサイズは512であり、これは誤った結果につながります)

  • cut -d' ' -f1 Macでは数値が右揃えになり、前にスペースが埋め込まれるため、機能しません。

したがって、柔軟なものが必要な場合は、perl-s演算子か、wc -cパイプで接続されますawk '{print $1}'(awkは先頭の空白を無視します)。

そしてもちろん、元の質問の残りについては、 -lt(または-gt)演算子を:

if [ $size -lt $your_wanted_size ]; then


3
+1; 算術コンテキスト(先頭の空白は無視される)でのみサイズを使用することがわかっている場合は、簡略化できますsize=$(wc -c < "$f")(数値を報告する<原因となるwcに注意してください)。再比較:より「bash-ful」if (( size < your_wanted_size )); then ...(そして[[ $size -lt $your_wanted_size ]])も忘れないでください
mklement0 2014年

3

gniourf_gniourfの回答に基づいて、

find "file.txt" -size -90k

file.txtのサイズがfile.txt90K未満の場合にのみ、stdoutに書き込みます。

「file.txt」を検索-size -90k -exec command \;

サイズが90K未満のcommand場合にコマンドを実行しfile.txtます。これをLinuxでテストしました。からfind(1)

…(-H-Lおよび-Pオプション)に続くコマンドライン引数は、「-」で始まる最初の引数まで、調査対象のファイルまたはディレクトリの名前と見なされます。

(強調を追加)。


1
ls -l $file | awk '{print $6}'

lsコマンドが列#6のファイルサイズを報告すると仮定する


1

私が使用するduのを--threshold、このために。このオプションがのすべてのバージョンで使用できるかどうかは不明ですduが、GNUのバージョンで実装されています。

du(1)のマニュアルからの引用:

-t, --threshold=SIZE
       exclude entries smaller than SIZE if positive, or entries greater
       than SIZE if negative

du --threshold=OPのユースケースに使用する私のソリューションは次のとおりです。

THRESHOLD=90k
if [[ -z "$(du --threshold=${THRESHOLD} file.txt)" ]]; then
    mail -s "file.txt size is below ${THRESHOLD}, please fix. " myemail@gmail.com < /dev/null
    mv -f /root/tmp/file.txt /var/www/file.txt
fi

その利点はdu、既知の形式でのオプションへの引数を受け入れることができることです-のように人間であるか10K10MiBそれとも快適であるか-手動で形式/単位間を変換する必要がないためdu処理。

参考SIZEまでに、manページのこの引数に関する説明を次に示します。

The SIZE argument is an integer and optional unit (example: 10K is 
10*1024). Units are K,M,G,T,P,E,Z,Y (powers of 1024) or KB,MB,... (powers
of 1000). Binary prefixes can be used, too: KiB=K, MiB=M, and so on.

+1優れたオプション。残念ながら私たちの一部はduそれをサポートしていない古いバージョンで立ち往生しています。この--thresholdオプションは、2013年リリースされたcoreutils 8.21で追加されました。
アミットNaidu

1

Macを使用している場合は、次のようにします。それだけです stat -f %z "/Users/Example/config.log"

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.