特定のファイルが特定のサイズの場合にのみコマンドを実行する方法

特定のファイルが特定のサイズの場合にのみコマンドを実行する方法

特定のファイルが定義されたサイズを超える場合にのみコマンドを実行するにはどうすればよいですか?どちらも最終的にcrontabで1行のコードで実行する必要があります。

擬似コード:

* * * * * find /cache/myfile.csv -size +5G && echo "file is > 5GB"

答え1

GNUがある場合は、そのオプションを使用してサイズを取得statできます。--printf

例えば

size=$(stat --printf '%s' /cache/myfile.csv)
if [ "$size" -gt 5368709120 ] ; then  # 5 GiB = 5 * 1024 * 1024 * 1024
  echo "file is > 5GB"
fi

man stat詳細より。


BSD stat(FreeBSDやMacなど)にも同様の書式設定オプションがあります-f

size=$(stat -f '%z' /cache/myfile.csv)

あるいは、Perlの組み込みstat関数または-sファイルテスト演算子を使用することもできます(bashのfile testに似ています-sが、ファイルが存在し空でない場合はtrueを返すのではなくファイルサイズを返します)。 Perlのstat関数は、次のデータ(からコピー)を含むファイルのメタデータの13要素リスト(配列)を返しますperldoc -f stat

[...] Not all fields are supported on all filesystem types. Here are
the meanings of the fields: 

  0 dev      device number of filesystem
  1 ino      inode number
  2 mode     file mode  (type and permissions)
  3 nlink    number of (hard) links to the file 
  4 uid      numeric user ID of file's owner
  5 gid      numeric group ID of file's owner
  6 rdev     the device identifier (special files only) 
  7 size     total size of file, in bytes
  8 atime    last access time in seconds since the epoch
  9 mtime    last modify time in seconds since the epoch
 10 ctime    inode change time in seconds since the epoch (*)
 11 blksize  preferred I/O size in bytes for interacting with the
             file (may vary from file to file)
 12 blocks   actual number of system-specific blocks allocated
             on disk (often, but not always, 512 bytes each) 

(The epoch was at 00:00 January 1, 1970 GMT.)

フィールド7は私たちに必要なフィールドです。

ファイルサイズを返すには(後でシェルコマンドまたはスクリプトで使用するために)、次のようにしますstat

# stat
perl -e 'print scalar((stat(shift))[7])' /cache/myfile.csv

# -s
perl -e 'print -s shift' /cache/myfile.csv

または、Perlを使用してすべての操作を実行できます。

# stat
perl -e 'print "File is > 5 GiB\n" if (stat(shift))[7] > 5*1024*1024*1024' /cache/myfile.csv

# -s
perl -e 'print "File is > 5 GiB\n" if -s shift > 5*1024*1024*1024' /cache/myfile.csv

perldoc -f statand perldoc -f -X(そしてhelp testbashで)を参照してください。

ただし、Perlのshift関数は、配列の最初の要素(デフォルトで@ARGV指定されていない場合はコマンドライン引数の配列)を削除し、その値を返します。配列のすべての要素を処理するためにループで頻繁に使用されますが、ここでは最初のパラメータ(ファイル名)にのみ興味があります。perldoc -f shift語彙の範囲やサブルーチンでの使用に関する注意事項を含む詳細については、参考資料を参照してください。

答え2

ファイルサイズを前提条件として使用するには、次の手順を実行します。使用statまたはfind:

[ -n "$(find /cache/myfile.csv -prune -size +5G 2>/dev/null)" ] && echo "file is > 5GB"

または、ターゲットコマンド(ここ)が短い場合は、[検索]セクションechoに入れてください。exec

find /cache/myfile.csv -prune -size +5G -exec echo "file is > 5GB" \;

もしも抜けを防ぐためにディレクトリ形式のファイルです-prunemyfile.csvfind

答え3

シェルがファイルを処理する必要がある場合は、両方のバージョンがすべての条件を満たしている場合にのみシェルのコマンドを実行します。ファイルで、名前が付けられており、myfile.csv> 5Gです。

find /cache -name 'myfile.csv' -type f -size +5G -exec bash -c '
    echo "$1 is > 5GB"
' bash {} \;

または

find /cache -name 'myfile.csv' -type f -size +5G -exec bash -c '
    for file; do echo "$file is > 5GB"; done
' bash {} +

答え4

一部のシェルには組み込み機能があります。

SHELL=/bin/tcsh
* * * * * if (-Z /cache/myfile.csv > 5*1024*1024*1024) echo 'file is > 5GiB'

またはzshここでglob修飾子と匿名関数を使用してを使用してください。ただし、zshにはstat GNUおよびBSD以前の組み込み関数もありますstat

SHELL=/bin/zsh
* * * * * (){ if (($#)) echo 'file is > 5GiB'; } /cache/myfile.csv(NLG+5)

find -size +5Gここではギガバイト(1GB = 1,000,000,000バイト)ではなくギガバイト(1GiB = 1,073,741,824バイト)について話しています。)

シンボリックリンクの場合、tcsh最終的に確認されるファイルのサイズを取得しますが、sなどの修飾子はシンボリックリンク自体のサイズを確認しますzshLG+5シンボリックリンクの解決されたサイズを確認するように変更されました。組み込み関数は、基本的にシンボリックリンクが解決された後にシンボリックリンクを変更するための情報を提供します。 GNUとBSDでは状況は逆です。シンボリックリンクに従うように指示するのと同じです。find-size-LG+5zshstat-Lstatfind-L

ファイルサイズを確認する方法については、次をご覧ください。Bashスクリプトからファイルサイズを取得するには?

関連情報