以前のperlのソース

初めてのPerl 第6版

初めてのPerl 第6版

共通ライブラリ
#-------------------------------------------------------------------------------
# mylib.pm
#-------------------------------------------------------------------------------
package mylib;


#-------------------------------------------------------------------------------
#【注意】
# 配列の引き渡しはリファレンスで行う
#-------------------------------------------------------------------------------
use utf8;
use Config::Simple;
use Data::UUID;
use Encode;
use File::Basename;
use File::Compare;
use File::Copy;
use File::Find::Rule;
use File::Path;
use File::Spec;
use File::Remove;
use List::Util;
use Sys::Hostname;
use Term::ANSIColor;
use Time::HiRes;
use Time::Piece;


################################################################################
# job
#      :インクルードディレクトリを表示
# in
#      :無し
# out
#      :無し
# exp
#      :mylib::print_include_dir();
###############################################################################
sub print_include_dir{
    print("#include dir:\n"); 
    foreach(&get_include_dir()){
        print($_."\n");    
    }
}


################################################################################
# job
#      :インクルードディレクトリを表示
# in
#      :無し
# out
#      :インクルードディレクトリ
# exp
#      :mylib::get_include_dir();
###############################################################################
sub get_include_dir{
    return @INC;
}


################################################################################
# job
#      :perlバージョンをを表示
# in
#      :無し
# out
#      :無し
# exp
#      :mylib::print_perl_version();
###############################################################################
sub print_perl_version{
    print("#perl verion:".&get_perl_version()."\n");    
}


################################################################################
# job
#      :perlバージョンを取得
# in
#      :無し
# out
#      :perlバージョン
# exp
#      :mylib::get_perl_version();
###############################################################################
sub get_perl_version{
    return $]; 
}


################################################################################
# job
#      :pidを表示
# in
#      :無し
# out
#      :無し
# exp
#      :mylib::print_pid();
###############################################################################
sub print_process_id{
    print("#pid:".&get_process_id()."\n");
}


################################################################################
# job
#      :script fileを表示
# in
#      :無し
# out
#      :無し
# exp
#      :mylib::print_script_file();
###############################################################################
sub print_script_file{
    print("#script file:".&get_script_file()."\n");
}


################################################################################
# job
#      :script file名を取得
# in
#      :無し
# out
#      :script_file名
# exp
#      :mylib::get_script_file();
###############################################################################
sub get_script_file{
    return $0;
}


################################################################################
# job
#      :perlのパスを表示
# in
#      :無し
# out
#      :無し
# exp
#      :mylib::print_perl_path();
###############################################################################
sub print_perl_path{
    my $cmd_str = 'which perl';
    my $result_qx = qx/$cmd_str/;
    print("#perl path:".$result_qx);
}

################################################################################
# job
#      :perlの環境情報を表示
# in
#      :無し
# out
#      :無し
# exp
#      :mylib::print_perl_info();
###############################################################################
sub print_perl_info{

    &print_perl_path();
    &print_perl_version();
    &print_include_dir();
    &print_script_file();
    &print_pid();
}


################################################################################
# job
#      :OS名を取得
# in
#      :なし
# out
#      :OS名
# exp
#      :my $os = mylib::get_os_name();
################################################################################
sub get_os_name{
    return $^O;    
}


################################################################################
# job
#      :プロセスIDを取得
# in
#      :なし
# out
#      :プロセスID
# exp
#      :my $os = mylib::get_process_id();
################################################################################
sub get_process_id{
    return $$;
}


################################################################################
# job
#      :ホスト名を取得
# in
#      :なし
# out
#      :ホスト名
# exp
#      :my $os = mylib::get_hostname();
################################################################################
sub get_hostname{
    return hostname();
}


################################################################################
# job
#      :ホスト名を取得
# in
#      :なし
# out
#      :ホスト名
# exp
#      :my $os = mylib::get_loginname();
################################################################################
sub get_loginname{
    return getlogin();
}


#-------------------------------------------------------------------------------
# job
#       :ファイル読み込み
# in
#      :読み込むファイル 
#      :エンコード文字列 (utf8,encoding(euc-jp),encoding(cp932))
# out
#      :行配列
# ex
#      :my @list = mylib::read_file("file.txt", "utf8");
#      :my @list = mylib::read_file("file.txt", "encoding(euc-jp)");
#      :my @list = mylib::read_file("file.txt", "encoding(cp932)");
#-------------------------------------------------------------------------------
sub read_file{
    my($file, $enc) = @_;
    
    if (!open(FH, "<:$enc", $file)){
        die("error :$!");
    }
    
    my @ret_list = ();
    
    #動かないときがあるので下記に修正
    #my @list = <FH>;
    #foreach my $data_line (@list){
    #  chomp($data_line);
    #  push(@ret_list, $data_line);
    #}
    
    while(<FH>){
        #print $_;
        my $line = $_;
        chomp($line);
        push(@ret_list, $line);
    }
    
    close(FH);

    return @ret_list;
}

#-------------------------------------------------------------------------------
# job
#       :ファイル 書き込み
# in
#      :保存するファイル
#      :配列のリファレンス
#      :エンコード文字列 (utf8,encoding(euc-jp),encoding(cp932))
# out
#      :なし
# ex
#      :mylib::write_file("wr_utf8.txt", \@list, "utf8");
#      :mylib::write_file("wr_euc.txt", \@list, "encoding(euc-jp)");
#      :mylib::write_file("wr_sjis.txt", \@list, "encoding(cp932)");
#-------------------------------------------------------------------------------
sub write_file{
    
    my ($file, $list_ref, $enc) = @_;

    if (!open(WFH, ">:$enc", "$file")){
        die("error :$!");
    }

    foreach my $line (@{$list_ref}){
        print WFH "$line\n"
    }

    close(WFH);
}


#-------------------------------------------------------------------------------
# job
#       :ファイル一覧を取得(再帰)
# in
#      :ディレクトリ
#      :対象ファイル種別 (*.ext)
# out
#      :ファイル一覧の配列
# ex
#      ::my @files = mylib::get_files_all_dir('./', '*.pl');
#-------------------------------------------------------------------------------
sub get_files_all_dir{
    
    my ($dir, $ext) = @_;
    
    my $rule = File::Find::Rule->new;
    $rule->file;
    $rule->name($ext);
    my @files  = $rule->in($dir);
    
    return @files;
}


#-------------------------------------------------------------------------------
# job
#       :ファイル一覧を取得
# in
#      :ディレクトリ
#       :対象ファイル種別 (*.ext)
# out
#      :file_list
# exp
#      :my @files = mylib::get_files_top_dir('.', '*.txt');
#-------------------------------------------------------------------------------
sub get_files_top_dir{

    my ($dir, $file) = @_;

    my $search = File::Spec->catfile( $dir, $file);

    return glob($search);
}


#-------------------------------------------------------------------------------
# job
#       :ディレクトリ直下のファイルを結合したファイルを作成
# in
#      :対象ディレクトリ
#       :対象ファイル種別 (*.ext)
# out
#      :結合したファイル
# exp
#      :my @files = mylib::create_cat_file_for_dir('.', '*.txt',"test_cat.txt", "utf8");
#-------------------------------------------------------------------------------
sub create_cat_file_for_dir{

    my ($dir, $file, $out_file, $enc) = @_;

    if (!open(WFH, ">:$enc", "$out_file")){
        die("error :$!");
    }

    my @files = &get_files_top_dir($dir, $file);
    foreach my $file (@files){
        my @lines = &read_file($file, "utf8");
        foreach my $line (@lines){
            print WFH "$line\n"
        }
    }
    
    close(WFH);
}


#-------------------------------------------------------------------------------
# job
#       :配列のユニーク処理
# in
#      :配列のリファレンス
# out
#      :ユニーク配列
# exp
#       :my @l = (1,2,3,1,2);
#      :my @ul = mylib::uniq_for_array(\@l);
#-------------------------------------------------------------------------------
sub uniq_for_array{

    my ($list_ref) = @_;

    my %seen = (); 
    my @uniqs = grep { ! $seen{$_} ++ } @{$list_ref};

    return @uniqs;
}


#-------------------------------------------------------------------------------
# job
#       :ファイル行のユニーク処理
# in
#      :入力ファイル
# out
#      :結果ファイル
# exp
#      :mylib::uniq_for_file("test.txt", "test_uniq.txt");
#-------------------------------------------------------------------------------
sub uniq_for_file{
    
    my ($in_file, $uniq_file) = @ARGV;
    
    if (!open(FH, "<:utf8", $in_file)){
        die("error :$!");
    }

    my $count = 0;    
    my %uniq_hash = ();
    
    while(my $line = <FH>){
        $count++;
        print("$count"."\r");
        chomp($line);
        
        if(!exists($uniq_hash{$line})){
            $uniq_hash{$line} = 1;
        }
    }
    close(FH);
    
    my @out_list = keys(%uniq_hash);

    #同パッケージ内の関数を呼ぶときは&をつけます
    &write_file($uniq_file, \@out_list,"utf8");
    
}


#-------------------------------------------------------------------------------
# job
#       :配列に登録されているデータ数を取得
# in
#      :配列のリファレンス
# out
#      :配列に登録されているデータ数
# exp
#       :my @arr = (1,2,3);
#       :print(mylib::get_array_count(\@arr));
#-------------------------------------------------------------------------------
sub get_array_count{
    
    my ($array_ref) = @_;
    return $#{$array_ref} + 1;
}

#-------------------------------------------------------------------------------
# job
#       :配列にの最大インデックスを取得
# in
#      :配列のリファレンス
# out
#      :配列にの最大インデックス
# exp
#       :my @arr = (1,2,3);
#       :print(mylib::get_array_max_index(\@arr));
#-------------------------------------------------------------------------------
sub get_array_max_index{
    
    my ($array_ref) = @_;
    return $#{$array_ref};
}


#-------------------------------------------------------------------------------
# job
#       :ハッシュに登録されているデータ数を取得
# in
#      :ハッシュのリファレンス
# out
#      :ハッシュに登録されているデータ数
# exp
#       :my %h = ();
#        $h{"a"} = 1;
#        $h{"b"} = 2;
#        print(mylib::get_hash_count(\%h));
#-------------------------------------------------------------------------------
sub get_hash_count{
    
    my ($hash_ref) = @_;
    
    my $count = keys( %{$hash_ref} );
    
    return $count;
}


#-------------------------------------------------------------------------------
# job
#       :ハッシュに登録されているデータ数を取得
# in
#      :ハッシュのリファレンス
# out
#      :ハッシュに登録されているデータ数
# exp
#       :my %h = ();
#        $h{"a"} = 1;
#        $h{"b"} = 2;
#        print(mylib::get_hash_count(\%h));
#-------------------------------------------------------------------------------
sub get_hash_keys{
    
    my ($hash_ref) = @_;
    
    return sort(keys( %{$hash_ref}));
}

#-------------------------------------------------------------------------------
# job
#       :ハッシュに登録されているデータ数を取得
# in
#      :ハッシュのリファレンス
# out
#      :ハッシュに登録されているデータ数
# exp
#       :my %h = ();
#        $h{"a"} = 1;
#        $h{"b"} = 2;
#        print(mylib::get_hash_values(\%h));
#-------------------------------------------------------------------------------
sub get_hash_values{
    
    my ($hash_ref) = @_;
    
    return sort(values(%{$hash_ref}));
}


#-------------------------------------------------------------------------------
# job
#       :現在時刻を取得
# in
#      :無し
# out
#      :現在時刻文字列
# exp
#       :my $str = mylib::get_time_now(); #2011/08/25 16:32:48
#-------------------------------------------------------------------------------
sub get_time_now{

    my $t = Time::Piece::localtime();
    my $time_str = sprintf("%04d/%02d/%02d %02d:%02d:%02d",$t->year,$t->mon,$t->mday,$t->hour,$t->minute,$t->sec);
    
    return $time_str;
}


################################################################################
# job
#      :ハッシュを作成
# in
#      :単語リストのリファレンス
# out
#      :ハッシュ
# exp
#      :my @l  = ("1","2","3");
#      :my %h = mylib::create_hash_from_word_list(\@l);
###############################################################################
sub create_hash_from_word_list{
    
    my($array_ref) = @_;

    print("create_hash_from_word_list\n");

    for my $index (0..$#{$array_ref}){
        my $word = ${$array_ref}[$index];
        print($word);
        
        if($word ne ""){
            $word_hash{$word} = 1;
        }
    }
    
    return %word_hash;
}


################################################################################
# job
#      :ハッシュをキーと値を表示
# in
#      :ハッシュのリファレンス
# out
#      :無し
# exp
#      :my @l  = ("1","2","3");
#      :my %h = mylib::create_hash_from_word_list(\@l);
#      :mylib::print_hash(\%h);
###############################################################################
sub print_hash{

    my($hash_ref) = @_;
    
    while( ($name, $value) = each %{$hash_ref} ){
        print ("key:[$name]\tvalue:[$value]\n");
    }
}


################################################################################
# job
#      :分割対象とする配列を分割、そのリファレンス配列を返す
# in
#      :分割対象とする配列のリファレンス
#      :分割グループ数
# out
#      :配列を分割した配列のリファレンス配列
# exp
#      :分割
#      :my @datas = (0,1,2,3,4,5,6,7,8,9,10);
#      :my @div_datas = mylib::div_array_data(\@datas, 3);
#      :
#      :#参照
#      :for(my $i = 0; $i <= $#div_datas; $i++){
#      :   print("top:$i\n");
#      :   my $data_ref = $div_datas[$i];
#      :   my $array_data_index = $#{$data_ref};
#      :           
#      :   for(my $j = 0; $j <= $array_data_index; $j++){
#      :       print("  child:".$data_ref->[$j]."\n");
#      :   }
#      :}
#
###############################################################################
sub div_array_data{
    
    my($array_ref, $div_array_count) = @_;
    
    my $max_array_index = $#{$array_ref};
    my $max_array_length =  $max_array_index + 1;
    
    #print("max_array_index:$max_array_index\n");
    #print("max_array_length:$max_array_length\n");
    
    ##データ分割
    my $div_count = int($max_array_length / $div_array_count) + 1;
    
    
    my @div_data_matome_array = ();
    my @tmp_data_array = ();
    my $out_count = 0;
    
    for(my $i = 0; $i <= $max_array_index; $i++){
        $out_count++;
        push(@tmp_data_array, $array_ref->[$i]);
        
        if($out_count >= $div_count){
            my @tmps = @tmp_data_array;
            push(@div_data_matome_array, \@tmps);
            #print("data - $i\n");
            @tmp_data_array = ();
            $out_count = 0;
        }
    }
    
    if($#tmp_data_array > 0){
        my @tmps = @tmp_data_array;
        push(@div_data_matome_array, \@tmps);
    }
    
    return @div_data_matome_array;
}


################################################################################
# job
#      :テキストにcabochaを実行する
# in
#      :テキストファイル
# out
#      :cabocha結果ファイル
# exp
#      :mylib::txt_to_caboca_for_file("test.txt", "test.cba");
###############################################################################
sub txt_to_caboca_for_file{

    my($input_file, $output_file) = @_;
    
    my $command = "cabocha -f1 $input_file > $output_file";
    
    eval{ 
        my $ret = system $command;
    };
    
    if ($@) {
        print("cabocha処理例外発生:$input_file\n");
    }
}


################################################################################
# job
#      :ディレクトリ内のテキストにcabochaを実行する
# in
#      :入力テキストディレクトリ
#      :ファイルの拡張子
# out
#      :出力Cabochaディレクトリ
# exp
#      :mylib::txt_to_caboca_for_dir("./txt", "*.txt", "./cba");
###############################################################################
sub txt_to_caboca_for_dir{
    
    my($input_dir, $ext, $output_dir) = @_;

    #出力ディレクトリ作成
    if(-d $output_dir){
        rmtree($output_dir);
    }
    mkdir($output_dir);    
    
    #対象ファイル読み込み
    my @files = &get_files_all_dir($input_dir, $ext);
    my $progress=0;
    
    for(my $i=0;$i <= $#files ;$i++){
        #print($files[$i]."\n");
        $progress = (($i+1) * 100) / ($#files + 1);
        print sprintf(" %3.0f", $progress) . "% \r";
        
        #ファイル処理
        #print($files[$i]."\n");
        my $file_name = "$files[$i]" . ".cba";
        $file_name = basename($file_name);
        my $output_file = File::Spec->catfile($output_dir, $file_name);
        
        my $command = "cabocha -f1 $files[$i] > $output_file";
        
        eval{ 
            my $ret = system $command;
        };
        
        if ($@) {
            print("cabocha処理例外発生:$files[$i]\n");
        }
    }
}


################################################################################
# job
#      :GUIDによるファイル名を作成
# in
#      :ファイルの拡張子
# out
#      :GUIDのファイル名
# exp
#      :mylib::create_guid_file_name(".txt");
#      :(例)0DCBFC3E-FA2D-11E0-8C54-E9B9A237EDC3.txt
###############################################################################
sub create_guid_file_name{

    my($ext) = @_;
    
    my $file_name = Data::UUID->new->create_str.$ext;
    return $file_name;
}


################################################################################
# job
#      :GUIDによるファイル名を作成(接頭辞を設定します)
# in
#      :プレフィックス文字
#      :ファイルの拡張子
# out
#      :GUIDのファイル名
# exp
#      :mylib::create_guid_file_name_add_prefix("type_",".txt");
#      :(例)type_962039C4-FA2D-11E0-A6CF-F8B9A237EDC3.txt
###############################################################################
sub create_guid_file_name_add_prefix{

    my($prefix, $ext) = @_;
    
    my $file_name = $prefix.Data::UUID->new->create_str.$ext;
    return $file_name;
}


################################################################################
# job
#      :処理時間計測開始(処理時間計測終了とペアで使用)
# in
#      :なし
# out
#      :開始時間
# exp
#      :my $start_time = mylib::stop_watch_start();
#      :my $time = mylib::stop_watch_stop($start_time);
###############################################################################
sub stop_watch_start{
    return Time::HiRes::time;
}


################################################################################
# job
#      :処理時間計測終了(処理時間計測開始とペアで使用)
# in
#      :開始時間
# out
#      :開始から終了までの時間(秒)
# exp
#      :my $start_time = mylib::stop_watch_start();
#      :my $time = mylib::stop_watch_stop($start_time);
###############################################################################
sub stop_watch_stop{
    my ($start_time) = @_;
    return Time::HiRes::time - $start_time;
}


################################################################################
# job
#      :処理時間計測終了、表示
# in
#      :開始時間
# out
#      :なし
# exp
#      :my $start_time = mylib::stop_watch_start();
#      :mylib::stop_watch_stop_and_print($start_time);
###############################################################################
sub stop_watch_stop_and_print{
    my ($start_time) = @_;
    printf("time:"."%0.3f(s)\n",Time::HiRes::time - $start_time); 
}


################################################################################
# job
#      :ディレクトリの作成(深いフォルダを作成)
# in
#      :ディレクトリ
# out
#      :なし
# exp
#      :mylib::make_dir_depth("./test1/test2/test3");
###############################################################################
sub make_dir_force{
    my ($tmp_dir) = @_;
    
    eval {
        if (-d $tmp_dir) {
            rmtree($tmp_dir);
        }
        
        mkpath [$tmp_dir] or die $!;
    };
    
    if ($@) {
      die $@;
    }   
}


################################################################################
# job
#      :ディレクトリの削除(存在する場合でも削除)
# in
#      :ディレクトリ
# out
#      :なし
# exp
#      :mylib::remove_dir_force("test");
###############################################################################
sub remove_dir_force{
    
    my ($tmp_dir) = @_;
    
    if ((tmp_dir ne '.') and (tmp_dir ne '..')) {
        if (-d $tmp_dir) {
            rmtree($tmp_dir);
        }       
    }
}


################################################################################
# job
#      :システムコマンド実行、結果を返す
# in
#      :システムコマンド文字列
# out
#      :実行結果
# exp
#      :my $reslt = mylib::system_command("ls -la");
###############################################################################
sub system_command{
    my ($cmd) = @_;
    
    my $result_qx = "";
    
    if($cmd ne ""){
        $result_qx = qx/$cmd/;
    }
    
    $result_qx =  decode('UTF-8', $result_qx);
    
    return $result_qx;
}


################################################################################
# job
#      :ファイルをコピー
# in
#      :コピー元ファイル
#      :コピー先ファイル
# out
#      :なし
# exp
#      :my $reslt = mylib::copy_file("a.txt", "b.txt");    ファイルをコピー    
#      :my $reslt = mylib::copy_file("a.txt", "./test");   ディレクトリへコピー
###############################################################################
sub copy_file{
    my ($src_file, $dest_file) = @_;
    
    File::Copy::copy($src_file, $dest_file) or die $!;
}

################################################################################
# job
#      :ファイルを移動
# in
#      :移動元ファイル
#      :移動先ファイル
# out
#      :なし
# exp
#      :my $reslt = mylib::move_file("a.txt", "b.txt");    ファイルを移動
#      :my $reslt = mylib::move_file("a.txt", "./test");   フォルダへコピー
###############################################################################
sub move_file{
    my ($src, $dest) = @_;
    
    File::Copy::move($src, $dest) or die $!;
}


################################################################################
# job
#      :配列からデータを検索
# in
#      :対象とする配列のリファレンス
#      :探すデータ文字列
# out
#      :検索結果配列
# exp1
#      :my @datas = (12,22,13,44);
#      :my $reslt = mylib::search_for_array(\@datas, "^1");
# exp2
#      :my @datas = ("apple","ace","big","cute");
#      :my @results = mylib::search_for_array(\@datas, "^a");
###############################################################################
sub search_for_array{
    my ($data_array_ref, $search_str) = @_;
    
    my @results = grep(/$search_str/, @{$data_array_ref});
    return @results;
}

################################################################################
# job
#      :splits処理
# in
#      :分割文字列
#      :対象文字列
# out
#      :分割結果配列
# exp
#      :my @datas = mylib::split_simple(",", "a,s,b,d");
###############################################################################
sub split_simple{
    my ($div_string, $str) = @_;
    
    return split(/$div_string/, $str);
}


################################################################################
# job
#      :ハッシュをマージ
# in
#      :ハッシュ1のリファレンス
#      :ハッシュ2のリファレンス
# out
#      :マージしたハッシュ
# exp
#      :my %hash1 = ("a" => 1, "b" => 2);
#      :my %hash2 = ("c" => 3, "d" => 4);
#      :my %hash3 = mylib::merge_hash(\%hash1, \%hash2);
###############################################################################
sub merge_hash{
    my ($hash_1_ref, $hash_2_ref) = @_;
    
    my %hash_merge = (%{$hash_1_ref}, %{$hash_2_ref});
    return %hash_merge;
}


################################################################################
# job
#      :ファイルの存在チェック
# in
#      :チェックするファイル
# out
#      :結果
# exp
#      :if(mylib::check_exist_file("test.txt")){
#      :   print("ファイルが存在します");
#      :} else {
#      :   print("ファイルが存在しません");
#      :}
###############################################################################
sub check_exist_file{
    my ($file) = @_;
    
    my $result = 0;
    if(-f $file){
        $result = 1;
    }
    
    return $result;
}


################################################################################
# job
#      :ディレクトリの存在チェック
# in
#      :チェックするディレクトリ
# out
#      :結果
# exp
#      :if(mylib::check_exist_dir("./data")){
#      :   print("ディレクトリが存在します");
#      :} else {
#      :   print("ディレクトリが存在しません");
#      :}
###############################################################################
sub check_exist_dir{
    my ($dir) = @_;
    
    my $result = 0;
    if(-d $dir){
        $result = 1;
    }
    
    return $result;
}


################################################################################
# job
#      :ファイルの削除
# in
#      :対象とするファイル
# out
#      :なし
# exp
#      :mylib::delete_file("test.txt");
################################################################################
sub delete_file{
    my ($file) = @_;
    
    unlink $file or die $!; 
}
 

################################################################################
# job
#      :ワイルドカードを使ったファイルの削除
# in
#      :対象とするワイルドカード
# out
#      :なし
# exp
#      :mylib::delete_file_by_wildcard("*.data");
################################################################################
sub delete_file_by_wildcard{
    my ($wild_card) = @_;
    
    File::Remove::remove $wild_card;
}


################################################################################
# job
#      :ファイルパスパース
# in
#      :対象とするファイルパス
# out
#      :パース結果(dir, name)
# exp
#      :my %tmp = mylib::parse_file_path("./data1/data2/test.txt");
#      :print($tmp{"dir"}."\n");
#      :print($tmp{"name"}."\n");
################################################################################
sub parse_file_path{
    my($file_path) = @_;
        
    my ($name, $dir, $ext) = fileparse($file_path);
    my %tmp_hash = ();
    $tmp_hash{"dir"} = $dir; 
    $tmp_hash{"name"} = $name;
    #$tmp_hash{"ext"} = $ext; 
    
    return %tmp_hash; 
}


################################################################################
# job
#      :フルパスを取得
# in
#      :対象とするファイルパス
# out
#      :フルパス
# exp
#      :my $fullpath = mylib::get_full_path("./data1/data2/test.txt");
#      :print($fullpath."\n");
################################################################################
sub get_full_path{
    my($file_path) = @_;
    
    return File::Spec->rel2abs($file_path);
}


#動かない? 保留
################################################################################
# job
#      :設定ファイルを読み込む
# in
#      :設定ファイル
# out
#      :設定オブジェクト
# exp
#      :my $cfg = mylib::read_config_file("app.ini");
#      :print(cfg->param("pass")."\n");
################################################################################
#sub read_config_file(){
#  my($config_file_path) = @_;
#  
#  my $cfgObj = new Config::Simple;
#  $cfgObj->read($config_file_path);
#  my $cfg = $cfgObj->vars();
#
#  return $cfg;
#}


################################################################################
# job
#      :ファイルを比較
# in
#      :ファイル1
#      :ファイル2
# out
#      :比較結果
# exp
#      :my $cfg = mylib::read_config_file("app.ini");
#      :print(cfg->param("pass")."\n");
################################################################################
sub compare_file{
    my($file1, $file2) = @_;

    if (File::Compare::compare($file1, $file2) == 0) {
        return 1;
    } else {
        return 0;
    }
}


################################################################################
# job
#      :正規表現:マッチ(option:gi)
# in
#      :チェック対象文字列
#      :チェックパターン文字列
# out
#      :結果
# exp
#      :my $check_str = "あいうえお";
#      :if(mylib::regex_match_simple($check_str,"^あい")){
#      :   print("match\n");
#      :}else{
#      :   print("no match\n");
#      :}
################################################################################
sub regex_match_simple{
    my ($check_str, $regex_str) = @_;
    
    if ($check_str =~ m/$regex_str/gi) {
        return 1;
    }
    return 0;    
}


################################################################################
# job
#      :正規表現:置換(option:gi)
# in
#      :チェック対象文字列
#      :チェックパターン文字列
#      :置換文字列
# out
#      :置換結果文字列
# exp
#      :my $check_str = "abc,def,gshi,abc";
#      :my $str = mylib::regex_replace_simple($check_str,"abc", "xyz");
################################################################################
sub regex_replace_simple{
    my ($check_str, $regex_str, $rep_str) = @_;
    
    my $str = $check_str;
    $str =~ s/$regex_str/$rep_str/gi;
    return $str;
}


################################################################################
# job
#      :配列の最大値を取得(数値対応)
# in
#      :対象とする配列
# out
#      :最大値
# exp
#      :my $check_str = mylib::get_max_for_array(@data);
################################################################################
sub get_max_for_array{
    my($array_ref) = @_;
    my @array_data =  @{$array_ref};
    return List::Util::max(@array_data);   
}


################################################################################
# job
#      :配列の最小値を取得(数値対応)
# in
#      :対象とする配列
# out
#      :最小値
# exp
#      :my $check_str = mylib::get_min_for_array(@data);
################################################################################
sub get_min_for_array{
    my($array_ref) = @_;
    my @array_data =  @{$array_ref};
    return List::Util::min(@array_data);   
}


################################################################################
# job
#      :配列の合計値を取得(数値対応)
# in
#      :対象とする配列
# out
#      :合計値
# exp
#      :my $check_str = mylib::get_sum_for_array(@data);
################################################################################
sub get_sum_for_array{
    my($array_ref) = @_;
    my @array_data =  @{$array_ref};
    return List::Util::sum(@array_data);
}


################################################################################
# job
#      :パスを結合する
# in
#      :ディレクトリパス
#      :ファイル名
# out
#      :結合したパス
# exp
#      :my $path = mylib::combine_path("./data1/data2", "test.txt");
################################################################################
sub combine_path{
    my($dir, $file) = @_;
    
    my $cpath = File::Spec->catfile($dir, $file);
    return $cpath;
}


################################################################################
# job
#      :文字コードをUTF-8へ変換
# in
#      :対象とする文字列
# out
#      :utf-8に変換した文字列
# exp
#      :my $result = mylib::enc_utf8($str);
################################################################################
sub enc_utf8{
    my($str) = @_;
    
    return Encode::encode('utf-8', $str);
}

sub dec_utf8{
    my($str) = @_;
    
    return Encode::decode('utf-8', $str);
}



################################################################################
# job
#      :色づけ表示
# in
#      :色指定 ("black","red","green","yellow","blue","magenta","cyan","white")
#      :文字列
# out
#      :なし
# exp
#      :my $result = mylib::enc_utf8($str);
################################################################################
sub print_color{
    my($color, $str) = @_;

    print color($color), $str, color("reset");
}


#-------------------------------------------------------------------------------
return 1;
WordPress用ライブラリ
#-------------------------------------------------------------------------------
# wplib.pm
#-------------------------------------------------------------------------------
package wplib;

#必須です
use strict;
use warnings;
use Encode;
use Encode qw(encode_utf8);
use File::Basename;
use File::Path;
use File::Spec;
use XMLRPC::Lite;

#文字コード
use utf8;
binmode STDIN, ":utf8";
binmode STDOUT, ":utf8";

#モジュール
require "mylib.pm";

#-------------------------------------------------------------------------------
# job  
#      :スレッドを新規登録する(新規からカテゴリは登録できない)
# in   
#      :ユーザー名
#      :パスワード
#      :エンドポイント
#      :ブログID
#      :タイトル
#      :ブログ記事本文
#      :ログ記事本文の「続き」部分
#      :ブログ記事の概要
#      :ブログ記事のキーワード
# out  
#      :postid
# memo
#      :パラメータ例)
#          my @categories =();
#          push(@categories, encode('utf-8' ,'国語'));
#          これをパラメータとして使用する ➡ \@categories
#
#      :結果取得例)
#      :my $result = entry_thread(...);
#      :if(!defined($result)){
#      :   #エラー
#      :}else{
#      :   #成功,postidを買えす
#      :   $result;
#      :}
#-------------------------------------------------------------------------------
sub entry_thread{
    my($username, $password, $endpoint, $blogid, $entry_title, $entry_body, $entry_more, $entry_excerpt, $entry_keyword, $categories_ref) = @_;

    my $result = XMLRPC::Lite
        -> proxy($endpoint)
        -> call('metaWeblog.newPost', $blogid, $username, $password,
            {
                #-- ブログ記事タイトル
                'title' => $entry_title,
                #-- ブログ記事本文
                'description' => $entry_body,
                #-- コメントを受け付けるかどうか(1でコメント受付)
                'mt_allow_comments' => 1,
                #-- トラックバックを受け付けるかどうか(1でトラックバック受付)
                'mt_allow_pings' => 1,
                #-- ブログ記事本文の「続き」部分
                'mt_text_more' => $entry_more,
                #-- ブログ記事の概要
                'mt_excerpt' => $entry_excerpt,
                #-- ブログ記事のキーワード
                'mt_keywords' => $entry_keyword,
                #-- カテゴリ
                'categories' => $categories_ref,
            },
            1
        )
        -> result;
        
    return $result;    
}


#-------------------------------------------------------------------------------
# job
#      :スレッドを更新登録する
# in   
#      :ユーザー名
#      :パスワード
#      :エンドポイント
#      :ポストID
#      :タイトル
#      :ブログ記事本文
#      :ログ記事本文の「続き」部分
#      :ブログ記事の概要
#      :ブログ記事のキーワード
#      :カテゴリ配列への参照
# out
#      :更新登録結果
# memo
#      :(例)
#          my @categories =();
#          push(@categories, encode('utf-8' ,'国語'));
#          これをパラメータとして使用する ➡ \@categories
#-------------------------------------------------------------------------------
sub update_thread{
    my($username, $password, $endpoint, $postid, $entry_title, $entry_body, $entry_more, $entry_excerpt, $entry_keyword, $categories_ref) = @_;
    
    my $result = XMLRPC::Lite
        -> proxy($endpoint)
        -> call('metaWeblog.editPost', $postid, $username, $password,
            {
                #-- ブログ記事タイトル
                'title' => $entry_title,
                #-- ブログ記事本文
                'description' => $entry_body,
                #-- コメントを受け付けるかどうか(1でコメント受付)
                'mt_allow_comments' => 1,
                #-- トラックバックを受け付けるかどうか(1でトラックバック受付)
                'mt_allow_pings' => 1,
                #-- ブログ記事本文の「続き」部分
                'mt_text_more' => $entry_more,
                #-- ブログ記事の概要
                'mt_excerpt' => $entry_excerpt,
                #-- ブログ記事のキーワード
                'mt_keywords' => $entry_keyword,
                #-- カテゴリ
                'categories' => $categories_ref,
            },
            1
        )
        -> result;

    return $result;
}


#-------------------------------------------------------------------------------
# job
#      :ブログ情報を取得します
# in
#      :ユーザー名
#      :パスワード
#      :エンドポイント
# out
#      :ブログ情報取得結果
#-------------------------------------------------------------------------------
sub get_blog_info{
    my($username, $password, $endpoint) = @_;
    
    my $rpc = XMLRPC::Lite->new();
    $rpc->proxy($endpoint);
    
    my $res = $rpc->call("blogger.getUsersBlogs",
                XMLRPC::Data->type('string', ''),
                XMLRPC::Data->type('string', $username),
                XMLRPC::Data->type('string', $password),
                );

    return $rpc;
    
}


#-------------------------------------------------------------------------------
# job
#      :ユーザー情報を取得します
# in
#      :ユーザー名
#      :パスワード
#      :エンドポイント
# out
#      :ブログ情報取得結果
#-------------------------------------------------------------------------------
sub get_user_info{
    my($username, $password, $endpoint) = @_;
    
    my $rpc = XMLRPC::Lite->new();
    $rpc->proxy($endpoint);
    
    my $res = $rpc->call("blogger.getUserInfo",
        "",
        $username,
        $password,
    )->result;

    return $res;
}

#-------------------------------------------------------------------------------
return 1;
2ch用ライブラリ
#-------------------------------------------------------------------------------
# nichanlib.pm
#-------------------------------------------------------------------------------
package nichanlib;

#必須です
use strict;
use warnings;
use File::Basename;
use File::Path;
use File::Spec;
use XMLRPC::Lite;
use Encode;
use Encode qw/ decode encode_utf8 /;
use LWP::UserAgent;
use HTML::TreeBuilder;



#文字コード
use utf8;
binmode STDIN, ":utf8";
binmode STDOUT, ":utf8";

#モジュール
require "mylib.pm";


#-------------------------------------------------------------------------------
# job  
#      :2cからカテゴリリンク情報を取得、ファイルに保存します
# in   
#      :取得メニューリンク
#      :作業用メニューリンクページ
#      :結果カテゴリリンクページ保存ファイル
# out  
#      :無し
# exp
#      :nichlib::get_2ch_bbs_menu('http://menu.2ch.net/bbsmenu.html', 'tmp_2ch_bbsmenu.html', '2ch_bbsmenu_link.tsv');
#-------------------------------------------------------------------------------
sub get_2ch_bbs_menu{
    
    #---------------------------------------- param
    my($menu_url, $tmp_2ch_bbs_menu_html_file, $save_2ch_bbs_menu_link_file) = @_;
    print("取得メニューリンク:$menu_url\n");
    print("作業用メニューリンクページ:$tmp_2ch_bbs_menu_html_file\n");
    print("結果カテゴリリンクページ保存ファイル:$save_2ch_bbs_menu_link_file\n");
    
    #---------------------------------------- get page
    print(" => get page\n");
    my $ua = LWP::UserAgent->new;
    $ua->agent('Mozilla/5.0 (Windows NT 5.1) AppleWebKit/535.1 (KHTML, like Gecko) Chrome/14.0.835.187 Safari/535.1');
    my $res = $ua->get($menu_url);
    $ua->parse_head(0);
    my $content = decode ( 'shiftjis', $res->content );
    my @content_array = ();
    push(@content_array, $content);
    
    #print(" -> save tmp file\n");
    &mylib::write_file($tmp_2ch_bbs_menu_html_file, \@content_array, 'utf8');
    
    
    #---------------------------------------- get link
    print(" => get link\n");
    my $tree = new HTML::TreeBuilder;
    $tree->parse_file($tmp_2ch_bbs_menu_html_file);
    $tree->eof(); 
     
    my @list = ();
    for my $a ( $tree->look_down("href", qr{http://} ) ) {
        my $line = join("\t", $a->attr_get_i('href'), decode( 'utf-8', $a->as_text));
        #print $line."\n";
        push(@list, $line);
    }
    
    $tree = $tree->delete;
    
    
    #---------------------------------------- save link
    print(" => save file\n");
    &mylib::write_file($save_2ch_bbs_menu_link_file, \@list, "utf8");
}


#-------------------------------------------------------------------------------
# job  
#      :2chのカテゴリのリンク情報から、記事一覧のリンクを取得
# in   
#      :入力:カテゴリURL
#      :入力:コメント数ハッシュのリファレンス
#      :入力:対象スレッド数
#      :出力:作業用ファイル
#      :出力:スレッドURL保存ファイル
#      :フィルタ文字ファイル
# out  
#      :無し
# exp
#      :nichlib::get_2ch_thread_link_for_category('http://yuzuru.2ch.net/comicnews/subback.html', \%thread_count_hash_ref, 300,'tmp_category.html', 'thread_url_file.tsv');
#-------------------------------------------------------------------------------
sub get_2ch_thread_link_for_category{

    #---------------------------------------- param
    my($menu_url, $comment_count_hash_ref, $target_thread_count, $tmp_category_file, $thread_url_file, $filter_word_datas_ref) = @_;
    print("カテゴリURL:$menu_url\n");
    print("コメント数ハッシュのリファレンス:$comment_count_hash_ref\n");
    print("作業用ファイル:$tmp_category_file\n");
    print("スレッドURL保存ファイル:$thread_url_file\n");
    
    #---------------------------------------- param
    print(" => get page\n");
    my $ua = LWP::UserAgent->new;
    $ua->agent('Mozilla/5.0 (Windows NT 5.1) AppleWebKit/535.1 (KHTML, like Gecko) Chrome/14.0.835.187 Safari/535.1');
    my $res = $ua->get($menu_url);
    $ua->parse_head(0);
    my $content= decode ( 'shiftjis' , $res->content );
    my @content_array = ();
    push(@content_array, $content);
    &mylib::write_file($tmp_category_file, \@content_array, 'utf8');
    
    #---------------------------------------- 記事ページ解析
    print(" => get thread\n");
    my $tree = new HTML::TreeBuilder;
    $tree->parse_file($tmp_category_file);
    $tree->eof();
         
    #base
    my $base_url = "";
    foreach my $tag ($tree->find("base")) {
        $base_url = $tag->attr('href');
        print ($base_url."\n");
        last;
    }
    
    #タイトルとリンクは全て同じフォーマットでは無い、タイトルはページから取得するのでここで必要ない、リンクのみを抽出する。
    my @list = ();
    for my $a ( $tree->look_down("href", qr{^\d} ) ) {
        my $tmp_url = $base_url.decode('utf-8', $a->attr_get_i('href'));
        $tmp_url =~ s/\/l50//go;
        
        #取得定義数以上、または前回より大きい場合はリンクとする
        my $tmp_title = decode('utf-8', $a->as_text);
        my $count = 0;
        
        if($tmp_title =~ /\((\d+)\)$/){
            $count = $1;
        }
        
        #対象とするスレッド数 以上の場合
        if($count >= $target_thread_count){
            
            #k下記の文字列が含まれている場合は対象とする
            #print($tmp_title."\n");
            #print($filter_str."\n");
            
            my @filter_str_datas = @{$filter_word_datas_ref};
            my $check_fds_flag = 0;
            
            foreach my $fsd(@filter_str_datas){
                
                if($fsd ne ""){
                    my $result = index($tmp_title, $fsd);
                    #print("$result\n");
                    if($result == -1){
                        next; #次をチェック
                    }else{
                        $check_fds_flag = 1;
                     last:    #チェックループを抜ける
                    }
                }
            }
            
            #文字列が対象に含まれていない場合は次をチェック
            if($check_fds_flag == 0){
                next;
            }
            
#          if($filter_str ne "none"){
#              my $result = index($tmp_title, $filter_str);
#              #print("$result\n");
#              if($result == -1){
#                  next;
#              }
#          }

            #前後のいらないものを削除
            $tmp_title =~ s/^\d{1,4}: //;
            $tmp_title =~ s/ \((\d+)\)$//;
            
            #前回よりスレッド数 より大きい場合hはチェック、そうでない場合は登録する
            my $before_count=0;
            #print("==========================>> ".$tmp_title."\n");
            if(exists($comment_count_hash_ref->{$tmp_title})){
                #print("==========================>> あるよ => ".$tmp_title."\n");
                
                $before_count = $comment_count_hash_ref->{$tmp_title};
                $before_count += 0;
                
                #更新登録
                if($count > $before_count){
                    my $tmp_text_url = join("\t", $tmp_url, $tmp_title, $count);
                    push(@list, $tmp_text_url);
                }
            }else{
                #print("==========================>> ないよ => ".$tmp_title."\n");
                
                #新規登録
                my $tmp_text_url = join("\t", $tmp_url, $tmp_title, $count);
                push(@list, $tmp_text_url);
            }
        }
    }
       
    $tree = $tree->delete;
    
    #--------------------------------- save link
    print(" => save file\n");
    &mylib::write_file($thread_url_file, \@list, "utf8");
}


#-------------------------------------------------------------------------------
# job  
#      :2c記事一覧のリンクから内容を取得します
# in   
#      :スレッドURLTSVファイル
#      :スレッド出力ディレクトリ
#      :処理待ち時間
# out  
#      :無し
# exp
#      :nichnlib::get_2ch_thread_contents('thread_url_file.tsv' './txt', 3);
#-------------------------------------------------------------------------------
sub get_2ch_thread_contents{
    
    #--------------------------------- param
    my($thread_url_file, $output_dir, $wait_time) = @_;
    print("スレッドURLファイル:$thread_url_file\n");
    print("出力ディレクトリ:$output_dir\n");
    print("処理待ち時間:$wait_time\n");
    
    #--------------------------------- 出力ディレクトリ作成
    if(!(-d $output_dir)){
        mkdir($output_dir);
    }
    
    #--------------------------------- ファイルからスレッドのリンクを抽出
    my @web_datas = ();
    my %thread_count_hash = ();
    print(" => read url file\n");
    my @list = &mylib::read_file($thread_url_file, "utf8");
    
    foreach my $l (@list){
        
        if($l eq ""){
            next;
        }
        
        #url
        my @datas = split(/\t/, $l);
        my $url = $datas[0];
        push(@web_datas, $url);
        
        #thread count
        my $title = $datas[1];
        my $count = $datas[2];;
        print("$title => $count\n");
        $thread_count_hash{$url} = $count;
    }
    
    #--------------------------------- スレッド取得
    foreach my $wd (@web_datas){
        
        print(" => get page:web data:$wd\n");
        my @data_array = ();
        my @split_address = split(/\//, $wd);
        #my $tmp_html_file_name = $split_address[-1].".html";
        my $tmp_html_file_name = "_tmp.html";
    
        my $url = $wd;
        my $ua = LWP::UserAgent->new;
        $ua->agent('Mozilla/5.0 (Windows NT 5.1) AppleWebKit/535.1 (KHTML, like Gecko) Chrome/14.0.835.187 Safari/535.1');
        my $res = $ua->get($url);
        
        if($res->is_success){
        
            $ua->parse_head(0);
            my $content = $res->decoded_content;
                
            #--------------------------------- 記事ページ解析
            print(" => get thread content\n");
            my $tree = new HTML::TreeBuilder;
            $tree->parse($content);
            $tree->eof();
                 
            #--------------------------------- タイトル
            my $title = "";
            foreach my $tag ($tree->find("h1")) {
                $title = $tag->as_text;
                print("タイトル:".$title."\n");
                push(@data_array, $title);
            }
            
            #--------------------------------- コメント数
            my $comment_count = $thread_count_hash{$wd};
            $comment_count += 0;
            push(@data_array, $comment_count);
                
            #--------------------------------- 記事を抽出(as_HTMLだと文字化けするが、as_XMLだときちんととれる)
            for my $a ( $tree->look_down("class", "thread" ) ) { 
                my $line = $a->as_XML;
                push(@data_array, $line);
            }
        
            #--------------------------------- 保存
            print(" => save file\n");
            my $file_name = $split_address[-2]."_".$split_address[-1].".txt";
            my $save_file = File::Spec->catfile($output_dir, $file_name);
            
            &mylib::write_file($save_file, \@data_array, "utf8");
            $tree = $tree->delete;
            
            sleep($wait_time);
        }else{
            #エラー
            print("get error:$url\n");
        }
    }
}


#-------------------------------------------------------------------------------
# job  
#      :2cから取得したスレッド内容の不要な部分を変換します
# in   
#      :スレッドページフォルダ
#      :スレッドページ編集結果フォルダ
# out  
#      :無し
# exp
#      :nichlib::convert_entry_text_from_thread_contents('$input_dir' '$output_dir');
#-------------------------------------------------------------------------------
sub convert_entry_text_from_thread_contents{
    
    #--------------------------------- param
    my($input_dir, $output_dir) = @_;
    print("スレッドページディレクトリ:$input_dir\n");
    print("スレッドページ編集結果ディレクトリ:$output_dir\n");
    
    #--------------------------------- 
    print(" => get files\n");
    my @files = mylib::get_files_all_dir($input_dir, "*.txt");

    print(" => convert files\n");
    foreach my $file (@files){
        print(" => $file\n");
        
        my@lines = mylib::read_file($file, 'utf8');
        my @output_lines = ();
        my $title = "";
        my $comment_count = 0;
        my $result = "";
        
        #スレッド内リンクを文字へ、メールリンクを文字へ変換
        for(my $i=0; $i <= $#lines ; $i++){
            
            #1行目はタイトル
            if($i == 0){
                $title = $lines[$i];
                next;
            }
            
            #2行目はコメント数
            if($i == 1){
                $comment_count = $lines[$i];
                next;
            }
            
            $result = $lines[$i];
            $result =~ s/(<a href=\"\.\.\/test\/read\.cgi.+?\">)(.+?)(<\/a>)/$2/g;
            #$result =~ s/(<a href=\"mailto:sage\">)(.+?)(<\/a>)/<font color=green>$2<\/font>/g;
            
            $result =~ s/(<a href=\"mailto:.*?\">).+?(<\/a>)/<font color=\"green\">名無しさん<\/font>/g;
            $result =~ s/(<font color=\"green\">).+?(<\/font>)/<font color=\"green\">名無しさん<\/font>/g;
            
                        
            #3行しかないので抜ける
            last;
        }
        
        push(@output_lines, $title);
        push(@output_lines, $comment_count);
        push(@output_lines, $result);

        #print($title."\n");
        #print($result."\n");
        
        my ($filename, $path, $suffix) = fileparse($file);
        my @tmp_paths = split(/\//, $path);
        my @tmp_paths_2 = @tmp_paths[1..$#tmp_paths];
        $path = join("/", @tmp_paths_2);
        my $tmp_dir = mylib::combine_path($output_dir, $path);
        #print("  => ".$tmp_dir."\n");
        
        if(!mylib::check_exist_dir($tmp_dir)){
            mylib::make_dir_force($tmp_dir);
        }
        
        my $fn = mylib::combine_path($tmp_dir, $filename);
        mylib::write_file($fn, \@output_lines, 'utf8');
    }
}


#-------------------------------------------------------------------------------
# job  
#      :2cから取得したスレッド内容に返信コメントに色を設定します
# in   
#      :スレッドページディレクトリ
#      :スレッドページ編集結果(色付け)ディレクトリ
# out  
#      :無し
# exp
#      :nichlib::convert_entry_text_from_thread_contents('$input_dir' '$output_dir');
#-------------------------------------------------------------------------------
sub convert_entry_text_from_thread_contents_color{

    #--------------------------------- param
    my($input_dir, $output_dir) = @_;
    print("スレッドページディレクトリ:$input_dir\n");
    print("スレッドページ編集結果(色付け)ディレクトリ:$output_dir\n");
    
    #--------------------------------- 
    print(" => get files\n");
    my @files = mylib::get_files_all_dir($input_dir, "*.txt");

    print(" => convert files\n");
    foreach my $file (@files){
        print(" => $file\n");
        
        my@lines = mylib::read_file($file, 'utf8');
        my $file_title = $lines[0];
        my $file_comment_count = $lines[1];
        my $contents = $lines[2];
        
        my $dl_header = "<dl class=\"thread\">";
        my $dl_footer = "</dl>";
        my $start_index = 0;
        my @output_datas = ();
        my $comment_count = 1;
        my %comment_hash = ();

        while(1){
            my $check_start_index = index($contents, "<dt>", $start_index);

            if($check_start_index == -1){
                last;
            }
        
            my $check_end_index =  index ($contents, "</dd>", $check_start_index);
            $check_end_index += 5;
            my $comment = substr($contents, $check_start_index, $check_end_index - $check_start_index );
            $comment_hash{$comment_count} = $comment;
        
            #my $check_cotain_start_index = index($comment, "<dd>", 0);
            #$check_cotain_start_index += 4;
            #my $check_cotain_end_index = index($comment, "</dd>", 0);
            #$comment_contain_hash{$comment_count} = substr($comment, $check_cotain_start_index, $check_cotain_end_index - $check_cotain_start_index);
            $comment_count++;
            $start_index = $check_end_index;
        }
        
        
        #@output_datas
        print(" => check コメントリンク\n");
        my %add_comment_hash = ();
        foreach my $key (sort(keys(%comment_hash))){
            my $comment = $comment_hash{$key};
        
            if($comment =~ /<dd>&gt;&gt;(\d+)/){
                if($comment =~ s/<dd>/<dd class="ret1">/){
                    $comment_hash{$key} = $comment ;
                    #print("$comment\n");
                }
            }
        }

        my @sort_keys = sort {$a <=> $b} keys(%comment_hash);


        push(@output_datas, $dl_header);
        foreach my $key (@sort_keys){
            push(@output_datas, $comment_hash{$key});
        }
        push(@output_datas, $dl_footer);
        my $output_datas_join = join("",@output_datas);
        #print("$output_datas_join\n");
        

        my @output_lines = ();
        push(@output_lines, $file_title);
        push(@output_lines, $file_comment_count);
        push(@output_lines, $output_datas_join);
        
        #保存
        my ($filename, $path, $suffix) = fileparse($file);
        my @tmp_paths = split(/\//, $path);
        my @tmp_paths_2 = @tmp_paths[1..$#tmp_paths];
        $path = join("/", @tmp_paths_2);
        my $tmp_dir = mylib::combine_path($output_dir, $path);
        #print("  => ".$tmp_dir."\n");
        
        if(!mylib::check_exist_dir($tmp_dir)){
            mylib::make_dir_force($tmp_dir);
        }
        
        my $fn = mylib::combine_path($tmp_dir, $filename);
        mylib::write_file($fn, \@output_lines, 'utf8');
    }
}

#-------------------------------------------------------------------------------
return 1;
2chワードプレス用処理
#-------------------------------------------------------------------------------
# nichanwp_manager.pm
#-------------------------------------------------------------------------------

#!/opt/local/bin/perl

#必須です
use strict;
use warnings;
use threads;
use threads::shared;
use File::Basename;
use File::Copy;
use File::Path;
use File::Spec;
use Time::HiRes;
use Readonly;
use Encode;

#文字コード
use utf8;
binmode STDIN, ":utf8";
binmode STDOUT, ":utf8";

require 'mylib.pm';
require 'nichanlib.pm';
require 'wplib.pm';

#-------------------------------------------------------------------------------
#  機能  
#      :2chのスレッドをwordpressへ登録する処理を管理する
#  入力
#      :カテゴリリンクファイル
#      :記事リンクディレクトリ
#      :記事内容ディレクトリ
#      :記事内容変換ディレクトリ
#      :記事内容カラー変換ディレクトリ
#      :対象とする記事数
#      :
#-------------------------------------------------------------------------------
#  ■アップロード処理                                                                                                                                             
#                                                                                                                                                          
#  取得したファイルから、管理用ファイルを作成。                                                                                                                  
#  
#  管理ID[カテゴリ_スレID]、スレッド名、ポストID、バイト数、ファイルパス、更新フラグ、スレッド数、データ落ちフラグ
#  
#  ファイルから、管理ID、スレッド名、行数を取得、管理用ファイルにデータの有無をチェック。                                                                                
#  管理用ファイルにデータがある場合は、バイト数が大きければ、バイト数数=最新のバイト数、更新フラグ=1、として更新する。 バイト数が小さければ更新しない(更新フラグが立っている場合は更新する)。            
#  管理用ファイルにデータがない場合は、管理ID(カテゴリ_スレID)、スレッド名、ポストID=-1、バイト数=最新のバイト数、更新フラグ=1を登録する。 とする。                                    
#                                                                                                                                                          
#  新規登録/更新処理
#  ポストIDと更新フラグを見て、新規登録/更新処理を行う。
#                                                                                                                                                          
#  新規登録/更新が成功した場合、ポストIDを更新、更新フラグ=0とする。
#  新規登録/更新が失敗した場合、ポストID=-1、更新フラグ=1とする。 
#  
#  
#  *スレッドは200以上のものを対象とする。
#  *スレッドのファイル毎回ダウンロードする。それが前回より行数が少ない場合はエラーだが、行数チェックによりアップされない。
#  *例外処理未実装
#  *データがない場合の処理未実装
#-------------------------------------------------------------------------------

#データファイルインデックス
Readonly my $DATA_INDEX_TITLE => 0;                    #記事タイトル
Readonly my $DATA_INDEX_COMMENT_COUNT => 1;            #コメント数
Readonly my $DATA_INDEX_CONTENTS => 2;             #記事内容


#管理データインデックス
Readonly my $MGR_INDEX_ID => 0;                        #管理ID[カテゴリ_スレID]
Readonly my $MGR_INDEX_THREAD_NAME => 1;           #スレッド名
Readonly my $MGR_INDEX_POST_ID => 2;               #ポストID
Readonly my $MGR_INDEX_FILE_PATH => 3;             #ファイルパス
Readonly my $MGR_INDEX_UPDATE_FLAG => 4;           #更新フラグ (未設定:-1, 設定:1)
Readonly my $MGR_INDEX_COMMENT_COUNT => 5;         #コメントカウント
Readonly my $MGR_INDEX_DATA_FROP_FLAG => 6;            #データ落ちフラグ

#管理ファイル
Readonly my $WP_MNG_FILE => "wp_mgr.txt";            
Readonly my $WP_MNG_FILE_BACK_DIR => "wp_mgr_back";          




#---------------------------------------- param
my($input_category_file, $thread_link_dir, $thread_contents_dir, $thread_contents_convert_dir, $thread_contents_convert_color_dir, $target_comment_count, $wait_time, $wait_time_for_wp, $filter_file) = @ARGV;


#フィルター単語を読み込む
my @filter_datas = mylib::read_file($filter_file, "utf8");


#
if(!mylib::check_exist_dir($WP_MNG_FILE_BACK_DIR)){
    mkdir($WP_MNG_FILE_BACK_DIR);
}else{
    if(mylib::check_exist_file($WP_MNG_FILE)){
        
        my ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) = localtime(time);
        my $date = sprintf("%04d%02d%02d_%02d%02d%02d", $year + 1900, $mon + 1, $mday, $hour, $min, $sec);
        my $back_file_name = $date."_".$WP_MNG_FILE;
        $back_file_name = mylib::combine_path($WP_MNG_FILE_BACK_DIR, $back_file_name);
        File::Copy::copy($WP_MNG_FILE, $back_file_name);
    }
}


#thread_linkd_dirが無い場合は作成
if(!mylib::check_exist_dir($thread_link_dir)){
    mkdir($thread_link_dir);
}else{
    mylib::remove_dir_force($thread_link_dir);
    mkdir($thread_link_dir);
}

#$thread_contents_dirが無い場合は作成
if(!mylib::check_exist_dir($thread_contents_dir)){
    mkdir($thread_contents_dir);
}else{
    mylib::remove_dir_force($thread_contents_dir);
    mkdir($thread_contents_dir);
}

#$thread_contents_convert_dirが無い場合は作成
if(!mylib::check_exist_dir($thread_contents_convert_dir)){
    mkdir($thread_contents_convert_dir);
}else{
    mylib::remove_dir_force($thread_contents_convert_dir);
    mkdir($thread_contents_convert_dir);
}

#$thread_contents_convert_color_dirが無い場合は作成
if(!mylib::check_exist_dir($thread_contents_convert_color_dir)){
    mkdir($thread_contents_convert_color_dir);
}else{
    mylib::remove_dir_force($thread_contents_convert_color_dir);
    mkdir($thread_contents_convert_color_dir);
}



#wordpress 基本情報
my $user = 'admin';
my $password = 'xxxxxxxxxxxxxxxxx';
my $endpoint = 'http://xxxxxxxx.sakura.ne.jp/wordpress/xmlrpc.php';
my $blogid = 1;




#---------------------------------------- カテゴリリンクの一覧を読み込み
print("================================================================================\n");
print("|  カテゴリリンクの一覧を読み込み:$input_category_file\n");
print("================================================================================\n");
my @tmp_category_lines = mylib::read_file($input_category_file, "utf8");
my @category_lines = ();

foreach(@tmp_category_lines){
    if($_ =~ /^#/){
        #これは対象外
    }else{
        push(@category_lines, $_);
    }
}

print(join("\n",@category_lines));


#---------------------------------------- 管理ファイルがある場合、スレッド名、スレッドカウントを取得
print("================================================================================\n");
print("|  管理ファイルがある場合、スレッド名、スレッドカウントを取得\n");
print("================================================================================\n");
my %wp_thread_comment_count_hash = (); #キーはスレッド名
my %wp_id_comment_count_hash = ();     #キーはID

if(mylib::check_exist_file($WP_MNG_FILE)){
    my @mngwp_lines = mylib::read_file($WP_MNG_FILE, 'utf8');
    
    foreach (@mngwp_lines){
        if($_ ne ""){
            my @datas = split(/\t/, $_);
            my $id = $datas[$MGR_INDEX_ID];
            #print("$id\n");
            my $tn = $datas[$MGR_INDEX_THREAD_NAME];
            #print("$tn\n");
            my $comment_count = $datas[$MGR_INDEX_COMMENT_COUNT];
            #print("$comment_count\n");
            $wp_thread_comment_count_hash{$tn} = $comment_count;
            $wp_id_comment_count_hash{$id} = $comment_count;
        }
    }
}


#---------------------------------------- カテゴリ毎に記事一覧のリンクを取得、ファイルに保存する、この一覧をダウンロードします
print("================================================================================\n");
print("|  カテゴリ毎に記事一覧のリンクを取得、ファイルに保存する (フィルタリング後、この一覧をダウンロードに使用)\n");
print("================================================================================\n");
foreach my $cl (@category_lines){
    if($cl ne "" ){
        my @div_tab = split(/\t/, $cl);
        my @div_slash = split('/', $div_tab[0]);
        my $category = $div_slash[-1];
        my $url = $div_tab[0]."subback.html";
        my $save_file_path = mylib::combine_path($thread_link_dir, $category.".txt");
        nichanlib::get_2ch_thread_link_for_category($url, \%wp_thread_comment_count_hash, $target_comment_count,'tmp_get_2ch_thread_link_for_category.txt', $save_file_path, \@filter_datas);
        print($url." => ".$save_file_path."\n");
        sleep($wait_time);
    }   
}


#---------------------------------------- 記事一覧リンク毎に記事内容を取得、ファイルに保存
print("================================================================================\n");
print("|  記事一覧リンク毎に記事内容を取得、ファイルに保存\n");
print("================================================================================\n");
my @link_files = mylib::get_files_top_dir($thread_link_dir, '*.txt');

foreach my $lf (@link_files){
    my @div_slash = split(/\//, $lf);
    my @div_dot = split(/\./, $div_slash[1]);
    my $hozon_dir = mylib::combine_path($thread_contents_dir, $div_dot[0]);

    #print("<$lf>\n");
    #print("<$thread_contents_dir>\n");
    #print("<$div_dot[0]>\n");
    #print("[$hozon_dir]\n");
    #next;

    #カテゴリ毎にディレクトリを作成
    if(!mylib::check_exist_dir($hozon_dir)){
        eval{
            mkpath( $hozon_dir );
        };
        
        if( $@ ){
            die "$hozon_dir を作成できません。$@";
        }
    }
    
    #記事リンクの内容をファイルに保存
    nichanlib::get_2ch_thread_contents($lf, $hozon_dir, $wait_time);
}


#---------------------------------------- 必要のないリンクをテキストへ変換
print("================================================================================\n");
print("|  記事内容の必要のないリンクをテキストへ変換\n");
print("================================================================================\n");
nichanlib::convert_entry_text_from_thread_contents($thread_contents_dir, $thread_contents_convert_dir);


#---------------------------------------- 記事内容にコメントにカラーを設定、これをアップします
print("================================================================================\n");
print("|  記事内容にコメントにカラーを設定\n");
print("================================================================================\n");
nichanlib::convert_entry_text_from_thread_contents_color($thread_contents_convert_dir, $thread_contents_convert_color_dir);



#---------------------------------------- wordpress有効チェック
print("================================================================================\n");
print("|  wordpress有効チェック\n");
print("================================================================================\n");
my $result_ui = wplib::get_user_info($user, $password, $endpoint);

#取得できない場合は、メンテナンス状態と見なし、終了します
if(!defined($result_ui)){
    print("==> wordpressが有効ではないので終了します\n");
    exit();   
}


#---------------------------------------- ファイルリストを抽出
print("================================================================================\n");
print("|  ファイルリストを抽出\n");
print("================================================================================\n");
my @upload_kouho_files = mylib::get_files_all_dir($thread_contents_convert_color_dir ,"*.txt");


#---------------------------------------- wp管理用ファイルを読み込み
print("================================================================================\n");
print("|  wp管理用ファイルを読み込み\n");
print("================================================================================\n");
my %mng_hash = ();

if(mylib::check_exist_file($WP_MNG_FILE)){
    my @mngwp_lines = mylib::read_file($WP_MNG_FILE, 'utf8');
    
    foreach (@mngwp_lines){
        if($_ ne ""){
            my @datas = split(/\t/, $_);
            my $id = $datas[$MGR_INDEX_ID];
            my $data = join("\t", @datas);
            print("$id\n");
            $mng_hash{$id} = $data;
            #print($data."\n");
        }
    }
}


#---------------------------------------- 取得したファイルとをwp管理データを比較
print("================================================================================\n");
print("|  取得したファイルとをwp管理データを比較、更新ファイルを作成\n");
print("================================================================================\n");
my %tmp_entry_data_hash = ();
foreach my $upk_file (@upload_kouho_files){
    
    my @suffix_list = qw /.txt/;
    my ($category_id, $path, $suffix) = fileparse($upk_file, @suffix_list);
    my @tmp_lines = mylib::read_file($upk_file,'utf8');

    if(exists($mng_hash{$category_id})){
        #更新:そのまま、更新処理の2択
        my $data = $mng_hash{$category_id};
        my @datas = split("\t", $data);
        $datas[$MGR_INDEX_UPDATE_FLAG] = -1;
        $datas[$MGR_INDEX_COMMENT_COUNT] = $tmp_lines[$DATA_INDEX_COMMENT_COUNT];
        my $entry = join("\t", @datas);;
        $tmp_entry_data_hash{$category_id} = $entry;
        
    }else{
        #新規とデータ落ちの場合
        my $title = $tmp_lines[$DATA_INDEX_TITLE];
        my $comment_count = $tmp_lines[$DATA_INDEX_COMMENT_COUNT];
        
        # 管理ID[カテゴリ_スレID]、スレッド名、 ポストID、ファイルパス、 更新フラグ、 コメント数、 データ落ちフラグ
        print("$upk_file\n");
        my $entry = "$category_id\t${title}\t-1\t${upk_file}\t-1\t${comment_count}\t0";
        $tmp_entry_data_hash{$category_id} = $entry;
    }
}

#管理ファイルのデータをコピー
#print("**********\n");
my %entry_data_hash = %mng_hash;

foreach my $key (keys(%tmp_entry_data_hash)){
    if(exists($entry_data_hash{$key})){
        #更新
        #print("更新:".$key."\n");
        $entry_data_hash{$key} = $tmp_entry_data_hash{$key};
    }else{
        #追加
        #print("追加:".$key."\n");
        $entry_data_hash{$key} = $tmp_entry_data_hash{$key};
    }
}

my @entry_datas = values(%entry_data_hash);

my @sorted_entry_datas = sort{
    my @datas_a = split("\t",$a);
    my @datas_b = split("\t",$b);
    $datas_a[4] <=> $datas_b[4]; } @entry_datas;

mylib::write_file($WP_MNG_FILE, \@sorted_entry_datas, 'utf8');


#---------------------------------------- wp管理データにより、wpの新規登録/更新処理を行う
print("================================================================================\n");
print("|  wp管理データにより、wpの新規登録/更新処理\n");
print("================================================================================\n");
my %mngwp_hash = ();
my @mngwp_lines = mylib::read_file($WP_MNG_FILE, 'utf8');

#管理データ読み込み、ハッシュへ
foreach (@mngwp_lines){
    my @datas = split(/\t/, $_);
    my $id = $datas[0];
    $mngwp_hash{$id} = join("\t", @datas);
}

#新規登録/更新登録
foreach my $key (keys(%mngwp_hash)){
    my $wait_flag = 1;
    print($key."\n");
    my $line = $mngwp_hash{$key};
    my @datas = split(/\t/,$line);
    
    my $post_id = $datas[$MGR_INDEX_POST_ID];
    $post_id += 0;
    
    my $entry_flag = $datas[$MGR_INDEX_UPDATE_FLAG];
    $entry_flag += 0;
    
    my $file = $datas[$MGR_INDEX_FILE_PATH];
    
    #更新対象の場合
    if($entry_flag == -1){
        if($post_id == -1){
            print(" => new_entry => $file\n");
            my %entry_hash = create_entry_data($file);
            my $categories_ref = $entry_hash{"entry_categories_ref"}; #カテゴリ
            my $keyword = $entry_hash{"keyword"};                     #キーワード
            my $title = $entry_hash{"title"};                         #タイトル
            $title = encode('utf-8', $title );
            my $text_body = $entry_hash{"text_body"};                 #内容_body
            $text_body = encode('utf-8', $text_body);
            my $text_more = $entry_hash{"text_more"};                 #内容_more
            $text_more = encode('utf-8', $text_more); 
            my $excerpt = "";                                           #概要
            
            #新規登録
            my $result =undef;
            
            while(1){
                my $checked = 0;

                eval{
                    $result = wplib::entry_thread($user, $password, $endpoint, $blogid, $title, $text_body, $text_more, $excerpt, $keyword, $categories_ref);
                };
                
                if($@){
                    $checked = 1;
                }else{
                    last;
                }
                
                if($checked == 1){
                    print("========================================> false sleep 600(sec)\n");
                    sleep(600)
                }
            }
            
            
            #結果
            if(!defined($result)){
                #エラー
                print(" => new_entry_false\n");
                my $tmp_mngwp = $mngwp_hash{$key};
                my @tmp_mngwp_datas = split("\t", $tmp_mngwp);
                #$tmp_mngwp_datas[$MGR_INDEX_POST_ID] = -1;                #ポストIDは -1 のまま
                #$tmp_mngwp_datas[$MGR_INDEX_UPDATE_FLAG] = -1;            #更新フラグは -1 のまま
                $tmp_mngwp_datas[$DATA_INDEX_COMMENT_COUNT] = -1;       #コメント数は -1 を設定
                $tmp_mngwp = join('\t', @tmp_mngwp_datas);
                $mngwp_hash{$key} = $tmp_mngwp;
            }else{
                #成功
                my $new_post_id = $result;
                print(" => new_entry_success => postid:$new_post_id\n");
                my $tmp_mngwp = $mngwp_hash{$key};
                my @tmp_mngwp_datas = split("\t", $tmp_mngwp);
                $tmp_mngwp_datas[$MGR_INDEX_POST_ID] = $new_post_id;  #ポストIDを設定
                $tmp_mngwp_datas[$MGR_INDEX_UPDATE_FLAG] = 1;           #更新フラグ1を設定
                $tmp_mngwp = join("\t", @tmp_mngwp_datas);
                $mngwp_hash{$key} = $tmp_mngwp;
            }
        }else{
            #update
            print(" => update_entry => $file\n");
            my %entry_hash = create_entry_data($file);
            my $categories_ref = $entry_hash{"entry_categories_ref"}; #カテゴリ
            my $keyword = $entry_hash{"keyword"};                     #キーワード
            my $title = $entry_hash{"title"};                         #タイトル
            $title = encode('utf-8', $title);
            my $text_body = $entry_hash{"text_body"};                 #内容_body
            $text_body = encode('utf-8', $text_body);
            my $text_more = $entry_hash{"text_more"};                 #内容_more
            $text_more = encode('utf-8', $text_more);
            my $excerpt = "";                                           #概要
            
            #更新登録
            my $result_update = undef;
            while(1){
                my $checked = 0;
                eval{
                    $result_update = wplib::update_thread($user, $password, $endpoint, $post_id, $title, $text_body, $text_more, $excerpt, $keyword, $categories_ref); 
                };
                
                if($@){
                    $checked = 1;
                }else{
                    last;
                }
                
                if($checked == 1){
                    print("========================================> false sleep 600(sec)\n");
                    sleep(600)
                }
            }
            
            #結果
            if(!defined($result_update )){
                #エラー
                print(" => update_entry_false\n");
                my $tmp_mngwp = $mngwp_hash{$key};
                my @tmp_mngwp_datas = split("\t", $tmp_mngwp);
                $tmp_mngwp_datas[$MGR_INDEX_UPDATE_FLAG] = -1;          #更新フラグはエラーのため -1 を設定
                $tmp_mngwp_datas[$DATA_INDEX_COMMENT_COUNT] = -1;       #コメント数は -1 を設定
                $tmp_mngwp = join('\t', @tmp_mngwp_datas);
                $mngwp_hash{$key} = $tmp_mngwp;

            }else{
                #成功
                print(" => update_entry_success\n");
                my $tmp_mngwp = $mngwp_hash{$key};
                my @tmp_mngwp_datas = split(/\t/, $tmp_mngwp);
                $tmp_mngwp_datas[$MGR_INDEX_UPDATE_FLAG] = 1;           #更新フラグは 1 を設定
                $tmp_mngwp = join("\t", @tmp_mngwp_datas);
                $mngwp_hash{$key} = $tmp_mngwp;
            }
        }
    }else{
        $wait_flag = 0;
        print(" => no work\n");    
    }
    
    if($wait_flag == 1){
        sleep($wait_time_for_wp);
    }
}


#wpへの新規登録/更新登録の結果をファイルに保存
print("================================================================================\n");
print("|  wpへの新規登録/更新登録の結果をファイルに保存\n");
print("================================================================================\n");
my @output_mngwp_datas = ();
foreach my $key (keys(%mngwp_hash)){
    my $line = $mngwp_hash{$key};
    #print("$line\n");
    push(@output_mngwp_datas, $line);
}

mylib::write_file($WP_MNG_FILE, \@output_mngwp_datas, 'utf8');

exit();







#-------------------------------------------------------------------------------
#  job
#      :t登録する記事ファイル
#  in
#      :登録ファイル
#  out
#      :登録情報のハッシュ
#-------------------------------------------------------------------------------
sub create_entry_data{
    my($file) = @_;

    my %tmp_hash = ();
    my @lines = mylib::read_file($file, "utf8");
    
    #カテゴリ
    my @suffix_list = qw /.txt/;
    my ($filename, $path, $suffix) = fileparse($file, @suffix_list);
    my @div_undes_datas = split(/_/, $filename);
    my $category = $div_undes_datas[0];
    my @entry_categories = ();
    push(@entry_categories, $category);
    $tmp_hash{"entry_categories_ref"} = \@entry_categories;
    
    #キーワード
    $tmp_hash{"keyword"} = $category;
    
    
    #タイトル
    my $entry_title = $lines[$DATA_INDEX_TITLE];
    $entry_title = delete_thread_count($entry_title);
    $tmp_hash{"title"} = $entry_title;
    
    #内容
    my $contents = $lines[$DATA_INDEX_CONTENTS];
    my %div_contents_hash = div_enrty_data($contents);
    $tmp_hash{"text_body"} = $div_contents_hash{"text_body"};
    $tmp_hash{"text_more"} = $div_contents_hash{"text_more"};

    return %tmp_hash;
}


#-------------------------------------------------------------------------------
#  job
#      :記事内容テキストを分割します
#  in
#      :記事内容テキスト
#  out
#      :分割した記事テキストハッシュ
#-------------------------------------------------------------------------------
sub div_enrty_data{
    my($text) = @_;
    my %tmp_hash = ();
    #my $check_str = '</dt>';
    my $check_str = '<dt>8';
    
    my $pos_index = index($text, $check_str);
    #$pos_index += length($check_str);
    my $text_body = substr($text, 0, $pos_index);
    
    my $len = length($text);
    $len -= $pos_index;
    my $text_more = substr($text, $pos_index, $len);

    #print("$pos_index\n");
    #print("$text_body\n");
    #print("$text_more\n");
    
    $tmp_hash{"text_body"} = $text_body;
    $tmp_hash{"text_more"} = $text_more;
    
    return %tmp_hash;
}


#-------------------------------------------------------------------------------
#  job
#      :記事のタイトルから記事数を削除します
#  in
#      :記事タイトル
#  out
#      :記事のタイトルから記事数を削除したテキスト
#-------------------------------------------------------------------------------
sub delete_thread_count{
    my ($title) = @_;
    
    my  $title_only = $title;
    $title_only =~ s/\s\(\d+\)$//;
    
    return $title_only;
}