フォルダのシリアル番号に基づいて失われたファイルを見つける方法

フォルダのシリアル番号に基づいて失われたファイルを見つける方法

DPXイメージを含むフォルダがあり、ファイル名が正しいことを確認したいと思います。

ファイル名の範囲は次のとおりです。

フレーム0000000.dpxからフレーム9999999.dpxまで

フォルダにこの範囲全体を含めることは不可能であり、上記の順序に含まれる任意の数字で始まり終わることができます。開始番号は常に終了番号より小さい。

どんな助けにも感謝します:-)

ベストアンサー1

#!/usr/bin/perl

# open the directory in the first arg (defaults to
# .) and get a sorted list of all files ending in
# .dpx into array @files
opendir(my $dir, shift // '.');
my @files = sort grep { /^Frame .*\.dpx$/ } readdir($dir);
close($dir);

# get the numeric value of the first and last
# element of the array
my ($first) = split /\./, $files[0];
my ($last)  = split /\./, $files[-1];

#print "$first\n$last\n";

# find and print any missing filenames
foreach my $i ($first..$last) {
  my $f = sprintf("%08i.dpx",$i);
  print "File '$f' is missing\n" unless -e $f
};

たとえば、として保存しfind-missing.plて実行可能にしますchmod +x find-missing.pl

まず、テストを実行するために一致するファイルの束をランダムに生成する必要があります(このテストでは10個以下のファイルで十分です)。

$ for i in {0..9} ; do
    [ "$RANDOM" -gt 16384 ] && printf "%08i.dpx\0" "$i" ;
  done | xargs -0r touch

$ ls -l *.dpx
-rw-r--r-- 1 cas cas 0 Feb 24 13:30 00000000.dpx
-rw-r--r-- 1 cas cas 0 Feb 24 13:30 00000001.dpx
-rw-r--r-- 1 cas cas 0 Feb 24 13:30 00000003.dpx
-rw-r--r-- 1 cas cas 0 Feb 24 13:30 00000005.dpx
-rw-r--r-- 1 cas cas 0 Feb 24 13:30 00000006.dpx
-rw-r--r-- 1 cas cas 0 Feb 24 13:30 00000007.dpx
-rw-r--r-- 1 cas cas 0 Feb 24 13:30 00000008.dpx

Bashでは、$RANDOM0から32767までの任意の数字が与えられるため、forループがファイルを生成する確率は約50%です。今回の実行では、00000002.dpx、00000004.dpx、00000009.dpxを除くすべての項目が生成されたことを確認できます。

次に、Perlスクリプトを実行します。

$ ./find-missing.pl .
File '00000002.dpx' is missing
File '00000004.dpx' is missing

00000009.dpx注:これは見つかった最大数のファイルを超えるため、言及されていません。これを行うには、$last適切な値でハードコードするか、コマンドライン引数から取得できます。


.Frame @ARGVGetSelect::標準またはGetopt::長い):

#!/usr/bin/perl

# Configuration variables
my $digits = 7;
my $prefix = 'Frame ';
my $suffix = '.dpx';

# Format string for printf
my $fmt = "$prefix%0${digits}i$suffix";

# Open the directory in the first arg (defaults to
# the current dir, ".") and get a sorted list of all
# files starting with $prefix and ending in $suffix
# into array @files
opendir(my $dir, shift // '.');
my @files = sort grep { /^$prefix.*$suffix$/ } readdir($dir);
close($dir);

# Get the numeric value of the first and last
# element of the array by removing the filename
# prefix (e.g. "Frame ") and suffix (e.g. ".dpx"):
my ($first, $last);
($first = $files[0])  =~ s/^$prefix|$suffix$//g;
($last  = $files[-1]) =~ s/^$prefix|$suffix$//g;

#print "$first\n$last\n";

# find and print any missing filenames
foreach my $i ($first..$last) {
  my $f = sprintf($fmt, $i);
  print "File '$f' is missing\n" unless -e $f
};

ちなみに、($first = $files[0]) =~ s/^$prefix|$suffix$//g;これは変数に値を割り当て、s///代替操作を介してそれを変更する一般的なPerl慣用語です。これは次のとおりです。

$first = $files[0];
$first =~ s/^$prefix|$suffix$//g;

合計ファイル数(および欠落ファイル数)を印刷するには、上記のバージョンの# find and print any missing filenames最後のコードブロック(およびそれ以降のすべてのエントリ)を次のように変更します。

# find and print any missing filenames
my $missing = 0;
foreach my $i ($first..$last) {
  my $f = sprintf($fmt, $i);
  if (! -e $f) {
    print "File '$f' is missing\n";
    $missing++;
  };
};

printf "\nTotal Number of files: %i\n", scalar @files;
printf "Number of missing files: %i\n", $missing;

これにより、次のような出力が生成されます。

$ ./find-missing2.pl 
File 'Frame 00000002.dpx' is missing
File 'Frame 00000003.dpx' is missing

Total Number of files: 7
Number of missing files: 2

おすすめ記事