ディレクトリ中のファイルサイズの合計値を再帰的に集計したい その2

Posted by Tatsuyano on Sun, Apr 7, 2013
In
Tags perl

前回のディレクトリ中のファイルサイズの合計値を再帰的に集計したい その1でmac用、linux用のワンライナーを関数として登録したのですが、 mac用のワンライナーが厳密には、期待した結果とは違うので、作り直してみました。

#!/usr/bin/env perl
use strict;
use constant DELETED_STDOUT    => "\x1b[1A";
use constant INITIALIZE_STDOUT => " ";

my $dir = $ARGV[0] || ".";
my $info = file_info($dir);

printf INITIALIZE_STDOUT;
print_info($info);

sub file_info {
  my $dir = shift;
  my @list = ();
  my $info = { file_size   => 0,
               directories => 0,
               files       => 0 };

  opendir(DIR, $dir) or die("Can not open directory:$dir ($!)");
  @list = readdir(DIR);
  closedir(DIR);

  foreach my $file (sort @list){
    next if $file =~ /^\.{1,2}$/;

    if( -d "$dir/$file" ){
      my $hash = file_info("$dir/$file");
      $info->{file_size}   += $hash->{file_size};
      $info->{directories} += $hash->{directories};
      $info->{files}       += $hash->{files};

      $info->{directories}++;
    }else{
      $info->{file_size} += -s "$dir/$file";
      $info->{files}++;
    }
  }

  print_info($info);
  printf DELETED_STDOUT;
  return $info;
}

sub print_info {
  my $info = shift;
  
  printf "%d directories, %d files, %s\n",
    $info->{directories},
    $info->{files},
    format_kmgt($info->{file_size});
}

sub format_kmgt {
  my $byte = shift;
  my @prefix = ("B","K","M","G","T");  

  while(1024 < $byte){
    $byte = $byte / 1024;
    shift @prefix;
  }

  return sprintf "%.1f%s",$byte,shift @prefix; 
}

1;

プログラムの置場所をどこにするべきか少し悩んだのですが、Dropbox以下にPATHを通したディレクトリを用意し、そこに置くことにしました。

mkdir /Users/$HOME/Dropbox/dotfile/mybin
chmod 755 /Users/$HOME/Dropbox/dotfile/mybin
chmod 755 /Users/$HOME/Dropbox/dotfile/mybin/bu
cat >> .zshrc export PATH=$PATH:$HOME/Dropbox/dotfile/mybin

perlのプログラムなので

/Users/$HOME/perl5/perlbrew/perls/perl-5.14.2/bin/

や、自前のプログラムということで、

/usr/local/bin

がいいのかもしれません。

参考サイト

以下のサイトを参考にさせていただきました。ありがとうございます!