数千のファイルを含むフォルダーを通過する perl スクリプトがあります。
スクリプトを書き始めたとき、私は perl の File::Find 関数を知らなかったので、構造内のすべてのファイルを一覧表示するために、次の行に沿って何かを使用しました。
open (FILES, "$FIND $FOLDER -type f |");
while (my $line = <FILES>) {...}
ただし、外部プログラムを起動する代わりに、perl からこれを実行しようと考えました。(File::Find の使い方を学びたいという以外に、この変更を行う本当の理由はありません。)
File::Find find 関数のセマンティクスを学ぼうとして、コマンド ラインでいくつかのことを試し、出力を find の出力と比較しました。
奇妙なことに、プログラム find が見つけたファイルが 1 つありますが、perl 関数はスキップします。
作品を探す:
machine:~# find /search/path -type f | grep UNIQ
/search/path/folder/folder/UNIQ/movie_file_015.MOV
/search/path/folder/folder/UNIQ/movie_file_145.MOV
/search/path/folder/folder/UNIQ/Thumbs.db
machine:~# find /search/path -type f | wc -l
6439
Perl は失敗します:
machine:~# perl -e 'use File::Find; find(sub { print $File::Find::name . "\n" if -f }, "/search/path");' | grep UNIQ
/search/path/folder/folder/UNIQ/movie_file_145.MOV
/search/path/folder/folder/UNIQ/Thumbs.db
machine:~# perl -e 'use File::Find; find(sub { print $File::Find::name . "\n" if -f }, "/search/path");' | wc -l
6438
ファイルを含めるのではなくフォルダーを除外するように変更すると、次のように機能します。
machine:~# perl -e 'use File::Find; find(sub { print $File::Find::name . "\n" unless -d }, "/search/path");' | grep UNIQ
/search/path/folder/folder/UNIQ/movie_file_015.MOV
/search/path/folder/folder/UNIQ/movie_file_145.MOV
/search/path/folder/folder/UNIQ/Thumbs.db
ファイル間の唯一の違いはサイズです:
machine:~# ls -l /search/path/folder/folder/UNIQ/
total 4213008
-rw-rw-r-- 1 user users 4171336632 May 27 2012 movie_file_015.MOV
-rw-rw-r-- 1 user users 141610616 May 27 2012 movie_file_145.MOV
-rw-rw-r-- 1 user users 20992 May 27 2012 Thumbs.db
問題のマシン上の Perl は古いものですが、古いものではありません。
machine:~# perl -version
This is perl, v5.8.8 built for sparc-linux
Copyright 1987-2006, Larry Wall
Perl may be copied only under the terms of either the Artistic License or the
GNU General Public License, which may be found in the Perl 5 source kit.
Complete documentation for Perl, including FAQ lists, should be found on
this system using "man perl" or "perldoc perl". If you have access to the
Internet, point your browser at http://www.perl.org/, the Perl Home Page.
これは既知のバグか何かですか?
または、「-f」のサイズ制限に達していますか? ファイルはほぼ 4 GB で、選択範囲内で最大です。
または、私のテスト (-f の場合) の選択が不十分ですか?
編集[ファイルを統計しようとしています]:
大きなファイルが失敗する
machine:~# perl -e 'use Data::Dumper; print Dumper(stat("/search/path/folder/folder/UNIQ/movie_file_015.MOV"));'
小さなファイルの作品
machine:~# perl -e 'use Data::Dumper; print Dumper(stat("/search/path/folder/folder/UNIQ/movie_file_145.MOV"));'
$VAR1 = 65024;
$VAR2 = 19989500;
$VAR3 = 33204;
$VAR4 = 1;
$VAR5 = 1004;
$VAR6 = 100;
$VAR7 = 0;
$VAR8 = 141610616;
$VAR9 = 1349281585;
$VAR10 = 1338096718;
$VAR11 = 1352403842;
$VAR12 = 16384;
$VAR13 = 276736;
バイナリ 'stat' は両方のファイルで機能します
machine:~# stat /search/path/folder/folder/UNIQ/movie_file_015.MOV
File: "/search/path/folder/folder/UNIQ/movie_file_015.MOV"
Size: 4171336632 Blocks: 8149216 IO Block: 16384 Regular File
Device: fe00h/65024d Inode: 19989499 Links: 1
Access: (0664/-rw-rw-r--) Uid: ( 1004/user) Gid: ( 100/ users)
Access: 2012-10-03 18:11:05.000000000 +0200
Modify: 2012-05-27 07:23:34.000000000 +0200
Change: 2012-11-08 20:44:02.000000000 +0100
machine:~# stat /search/path/folder/folder/UNIQ/movie_file_145.MOV
File: "/search/path/folder/folder/UNIQ/movie_file_145.MOV"
Size: 141610616 Blocks: 276736 IO Block: 16384 Regular File
Device: fe00h/65024d Inode: 19989500 Links: 1
Access: (0664/-rw-rw-r--) Uid: ( 1004/user) Gid: ( 100/ users)
Access: 2012-10-03 18:26:25.000000000 +0200
Modify: 2012-05-27 07:31:58.000000000 +0200
Change: 2012-11-08 20:44:02.000000000 +0100
また:
machine:~# perl -e 'stat("/search/path/folder/folder/UNIQ/movie_file_145.MOV"); print $! . "\n";'
Bad file descriptor
machine:~# perl -e 'stat("/search/path/folder/folder/UNIQ/movie_file_015.MOV"); print $! . "\n";'
Value too large for defined data type
EDIT2:
# perl -V | grep "uselargefiles|FILE_OFFSET_BITS"
config_args='-Dccflags=-DDEBIAN -Dcccdlflags=-fPIC -Darchname=sparc-linux -Dprefix=/usr -Dprivlib=/usr/share/perl/5.8 -Darchlib=/usr/lib/perl/5.8 -Dvendorprefix=/usr -Dvendorlib=/usr/share/perl5 -Dvendorarch=/usr/lib/perl5 -Dsiteprefix=/usr/local -Dsitelib=/usr/local/share/perl/5.8.8 -Dsitearch=/usr/local/lib/perl/5.8.8 -Dman1dir=/usr/share/man/man1 -Dman3dir=/usr/share/man/man3 -Dsiteman1dir=/usr/local/man/man1 -Dsiteman3dir=/usr/local/man/man3 -Dman1ext=1 -Dman3ext=3perl -Dpager=/usr/bin/sensible-pager -Dstatic_ext=B ByteLoader GDBM_File POSIX re -Dusemymalloc -Uuselargefiles -Uafs -Ud_csh -Uusesfio -Uusenm -Duseshrplib -Dlibperl=libperl.so.5.8.8 -Dd_dosuid -des'
useperlio=define d_sfio=undef uselargefiles=undef usesocks=undef
問題が解決しました":
machine:~# perl -e 'stat("/search/path/folder/folder/UNIQ/movie_file_015.MOV"); print $!{EOVERFLOW} . "\n";'
92
machine:~# perl -e 'stat("/search/path/folder/folder/UNIQ/movie_file_145.MOV"); print $!{EOVERFLOW} . "\n";'
0
作品:
# perl -e 'use File::Find; find(sub { print $File::Find::name . "\n" if -f or ( $!{EOVERFLOW} > 0 and not -d) }, "/search/path");' | grep UNIQ
/search/path/folder/folder/UNIQ/movie_file_015.MOV
/search/path/folder/folder/UNIQ/movie_file_145.MOV
/search/path/folder/folder/UNIQ/Thumbs.db