当我开始编写脚本时,我不知道perl File :: Find函数,所以为了列出结构中的所有文件,我使用了以下的一些东西:
open (FILES,"$FIND $FOLDER -type f |"); while (my $line = <FILES>) {...}
现在,我想我会尝试从perl这样做,而不是启动一个外部程序.
(没有真正的理由做这个改变,除了想要学习使用File :: Find.)
尝试学习File :: Find find功能的语义我在命令行中尝试了几件事情,并将输出与find进行了比较.
查找作品:
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.
这是一个已知的bug还是什么?
或者我碰到一些“-f”的大小限制?该文件几乎是4gb,是最大的选择.
还是我的考试(如果-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
解决方法
要检查是否是这种情况,请运行:
perl -V | grep "uselargefiles|FILE_OFFSET_BITS"
如果您的perl具有大量文件支持,则输出应显示为uselargefiles = define和-D_FILE_OFFSET_BITS = 64.如果没有,那么你的perl很可能不支持大文件.
这可能有点令人困惑,为什么需要大的文件支持,即使只是说明文件.基本的问题是,stat(2)系统调用的32位版本,而不是返回虚假大小,只有在应用于大于2GB的文件时,才会使用EOVERFLOW进行失败:
“EOVERFLOW
(stat()) path refers to a file whose size cannot be represented in the type off_t. This can occur when an application compiled on a 32-bit platform without -D_FILE_OFFSET_BITS=64 calls stat() on a file whose size exceeds (1<<31)-1 bits.”
在技术上,接收到这个错误应该足以表明命名文件确实存在(尽管我猜想它也可能是一个非常好的目录),但是perl不够聪明,不能意识到 – 它只是看到stat失败了,所以没有回报.
(编辑:由于ikegami在注释中正确注释,如果stat(2)调用失败,-f返回undef而不是0或1,并将$!设置为导致失败的错误代码,所以如果你不介意假设所有大小为> 2GB的目录条目都是文件,您可以执行一些类似于-f $_或(-f _和$!{EOVERFLOW})来检查它.