概要

  • ディレクトリを再帰的に処理するサンプル。

ソースコード

Win32::Unicode::Native 版

# ファイル名のリストアップ, ファイル名の長さ付き

use strict;
use warnings;
use utf8;
use Encode;
use Win32::Unicode::Native;

my $charsetFile		= 'UTF-8';

my $fileNameOut = "FileNames.txt";
my @targetDirs = map { 'D:/' . $_; } qw(
	aaa bbb ccc
);

my $prevDir = '';

open( my $OUT, '>', $fileNameOut ) or die( "$fileNameOut: $!\n" );
binmode( $OUT, ":encoding($charsetFile)" );
find( \&getName, @targetDirs );
close( $OUT );

sub getName
{
	my $args = shift;
	my $curFile = $args->{name};
	my $curDir  = $args->{dir};
	if ( $prevDir ne $curDir ){
		print( "$curDir\n" );
		$prevDir = $curDir;
	}
	printf $OUT ( "%d\t%s\n", length( $curFile ), $curFile );
}

# EOF

File::Next 版

# ファイル名のリストアップ, ファイル名の長さ付き

use strict;
use warnings;
use utf8;
use Encode;
use File::Next;
use Path::Class;
use Win32;

#my $charsetConsole	= 'UTF-8';
my $charsetConsole	= 'CP932';
my $charsetFile		= 'UTF-8';

binmode( STDIN,  ":encoding($charsetConsole)" );
binmode( STDOUT, ":encoding($charsetConsole)" );
binmode( STDERR, ":encoding($charsetConsole)" );

my $fileNameOut = "FileNames.txt";

# 「RECYCLER」を拾わないように
my @targetDirs = map{ encode( $charsetConsole, 'D:/' . $_ ); } qw(
	aaa bbb ccc
);

my $prevDir = '';
my $nextFiles = File::Next::files( @targetDirs );

open( my $OUT, ">:encoding($charsetFile)", encode( $charsetConsole, $fileNameOut ) ) 
	or die( "$fileNameOut: $!\n" );
while( defined ( my $file = $nextFiles->() ) ){
	# $file は CP932 エンコードかつ短いファイルネーム
	my $curFile = getUtf8PathName( $file );
	my $curDir = getUtf8PathName( file( $file )->dir );
	if ( $prevDir ne $curDir ){
		print "$curDir\n";
		$prevDir = $curDir;
	}
	printf $OUT ( "%d\t%s\n", length( $curFile ), $curFile );
}
close( $OUT );

sub getUtf8PathName
{
	my $path = shift;
	$path = Win32::GetLongPathName( $path );
	if ( ! Encode::is_utf8( $path ) ){
		$path = decode( $charsetConsole, $path );
	}
	return $path;
}

# EOF

自前で再帰版

#!/usr/local/bin/perl

# カレントディレクトリ以下の全てのファイルを処理する。

recursive( '.' );

exit();

##### Subroutine

# 再帰的にコピーする
# @param[in]	$sBaseDir	基準となるディレクトリ
sub recursive
{
	my( $sBaseDir ) = @_;
	my( @FileLists, $sFileName );

	@FileLists = glob( $sBaseDir.'/*' );

	foreach $sFileName ( sort( @FileLists ) ){
		if ( -d $sFileName ){
			# ディレクトリだったら再帰呼び出し
			&recursive( $sFileName );
		} elsif ( -f $sFileName ){
			# ファイルだったら処理する
			print( $sFileName . "\n" );
		}
	}
}

# EOF

リンク