技術メモ

神奈川在住のITエンジニアの備忘録。おもにプログラミングやネットワーク技術について、学んだことを自分の中で整理するためにゆるゆると書いています。ちゃんと検証できていない部分もあるのでご参考程度となりますが、誰かのお役に立てれば幸いです。

ディレクトリ配下の全ファイルの文字コードを一覧で出す

久々にperlスクリプトを作成した。作ったのは、指定したディレクトリ配下を再帰的に辿り、存在する全ファイルの文字コードを一覧で出すというもの。以下のようにして実行する。

perl printCharCode.pl "対象のディレクトリ"


printCharCode.pl の内容は以下の通り。

use strict;
use warnings;
use Encode::Guess;

my $dir = $ARGV[0];
if(! -d $dir) {
    die "Invalid argument. Specify a dir...";
}

my @fileList;
getFileList($dir, \@fileList);

foreach my $file (sort @fileList) {
    open(my $fh, $file) or die "Failed to open $file: $!";
    my $fileContent;
    while (my $line = <$fh>){
        $fileContent .= $line;
    }
    close($fh);

    # https://perldoc.perl.org/Encode/Guess.html を参考にした。
    # 「By default, it checks only ascii, utf8 and UTF-16/32 with BOM.」
    # とのことなので、guess_encoding の引数に utf8、UTF-16/32 は指定しなくて良いらしい。
    my $encode = guess_encoding($fileContent, qw/euc-jp shiftjis 7bit-jis/);
    if (ref $encode) {
        print "Encoding is " . $encode->name . " for " . $file . ".\n";
    }
    else {
        print "Can't guess $file: $encode\n";
    }
}

sub getFileList {
    my $dir = shift;
    my $ref_fileList = shift; # for output.
    
    opendir(my $dh, $dir) or die "Failed to open $dir: $!";
    my @fileList = readdir($dh);
    closedir($dh);
    
    foreach my $file (sort @fileList) {
        if($file =~ /^\.{1,2}$/) {
            next;
        }
        if( -d "$dir/$file") {
            getFileList("$dir/$file", $ref_fileList);
        }
        else {
            push(@$ref_fileList, "$dir/$file");
        }
    }
}


実行結果は以下のようになる。
(例)

Encoding is shiftjis for xxxx
Encoding is utf8 for yyyy
Encoding is ascii for zzzz