日本語のフォルダやファイルの中から、特定の拡張子のファイルを探して、ALL_Files.txtというテキストファイルに出力するサンプルです。
SJISをデコード、エンコードするタイミングが、とても大事です。
繰り返しますが、ソースファイルは、必ずUTF-8で保存してください。
#!/usr/bin/perl
# 再帰的呼び出しを行いながら、全てのxxx.mkv,xxx.mp4ファイルのフルパスをALL_Files.txtに出力する。
#必ずソースをUTF-8で記載すること。
use strict;
use warnings;
use Encode;
use utf8;
binmode STDIN, ":encoding(cp932)"; # 入力なのに、何故かencoding
binmode STDOUT, ":encoding(cp932)";
binmode STDERR, ":encoding(cp932)";
# ファイルハンドル<IN>等からの入力時はdecodeが必要
# ファイルハンドル<OUT>等への出力時はencodeが必要
our $debug=0;
our $ScriptDir=$0; #実行中のplスクリプトフルパス
$ScriptDir=&de_sjis($ScriptDir);
$ScriptDir=~s/\\[^\\]+\.pl$//;
&vv('$ScriptDir',$ScriptDir);
open(OUT,'>ALL_Files.txt');
# 再帰的呼び出しを行うサブルーチンを呼び出す
&showdir($ScriptDir,'');
close(OUT);
exit;
#============================
sub showdir {
my($rootdir,$indir) = @_;
print $rootdir.$indir,"\n";
# ディレクトリに含まれるすべてのファイル名、ディレクトリ名を取り出す(SJIS)
opendir(INDIR, &en_sjis($rootdir.$indir.'\\')); # || die $!;
my(@files) = readdir(INDIR); # @files 配列にはSJISの名称が保存される。
closedir(INDIR);
for my $fname (@files){
$fname=&de_sjis($fname); # SJISをPerl内部コードにデコードする。
&vv('$fname',$fname);
if($fname ne '.' && $fname ne '..') {
my $path = $indir . '\\' . $fname;
if(-d &en_sjis($rootdir.$path)){
# ディレクトリなら、再帰呼び出し
&showdir($rootdir,$path);
} else {
#ファイルなら、拡張子のチェック
if ($fname =~/\.(mp4|mkv)$/i) { #iオプションは正規表現で大文字と小文字を区別しないモード
print OUT &en_sjis($rootdir.$path."\n"); # SJISにエンコードしてからファイルに出力する。
}
}
}
}
}
#----------------------------------
sub en_sjis
{
my ($buf)=@_;
encode('cp932',$buf);
}
sub de_sjis
{
my ($buf)=@_;
decode('cp932',$buf);
}
sub en_utf8
{
my ($buf)=@_;
encode('utf-8',$buf);
}
sub de_utf8
{
my ($buf)=@_;
decode('utf-8',$buf);
}
sub en_euc
{
my ($buf)=@_;
encode('euc-jp',$buf);
}
sub de_euc
{
my ($buf)=@_;
decode('euc-jp',$buf);
}
sub ccode
{
my ($str,$count)=@_;
my $output='';
for (my $i=1;$i<=$count;$i++) {
my $c=substr($str,$i-1,1);
my $cc=ord($c);
$output.=sprintf('%2.2X ',$cc);
}
return $output;
}
sub vv
{
my($Name,$Value)=@_;
if($debug) {
print $Name.'=['.$Value.']',"\n";
}
}
1;