data.cgiの文字コードをUTF-8に変換する方法

このQ&Aのポイント
  • data.cgiの文字コードをUTF-8に変換する方法を教えてください。
  • 現在、data.cgiの文字コードはSJISですが、UTF-8に変換したいです。
  • xrea.comのサーバを利用しており、上記のスクリプトを実行するとサーバエラーが発生しています。
回答を見る
  • ベストアンサー

UTF-8に変換

open( IN, "data.cgi" ); @f_data = <IN>; close( IN ); $i = '1'; open( OUT, ">log.cgi" ); select OUT; foreach( @f_data ){ if( $i > 10 ){ last; } ( $f_data1, $f_data2, $f_data3, $f_data4 ) = split( /<>/ ); $f_data1 =~ s/ //g; print "$f_data1階 $f_data4\n"; $i++; } #書き出し先ファイルを閉じる select STDOUT; close( OUT ); 上記スクリプトでlog.cgiに書き出される文字コードをUTF-8に変換したいのですが、いろいろな解説サイトの説明通りに行うと、私のやり方が間違っているだけだと思いますが、サーバエラーになっていまいます。サーバはxrea.comを利用しております。 data.cgiの文字コードはSJISです。 上記スクリプトの場合は、どのように変更すればよろしいのでしょうか?宜しくお願いいたします。

  • MKNET
  • お礼率94% (89/94)
  • Perl
  • 回答数5
  • ありがとう数6

質問者が選んだベストアンサー

  • ベストアンサー
  • sakusaker7
  • ベストアンサー率62% (800/1280)
回答No.5

ではシェルでの作業をしない場合の手順を。 記憶があやふやな部分がありますので、どっか間違っているかもしれません。 何か問題があったらいってください。 まずJcode-2.06.tar.gzをダウンロードするのは同じです。 手元のマシンの適当なディレクトリでアーカイブをといてください。 cd Jocde-2.06 すると、以下のようなファイルとディレクトリが見えます。 ドライブ D のボリューム ラベルがありません。 ボリューム シリアル番号は AC5F-5FE1 です D:\work\jcode\Jcode-2.06 のディレクトリ 2006/12/16 04:28 <DIR> . 2006/12/16 04:28 <DIR> .. 2006/07/02 16:56 2,932 Changes 2006/07/02 16:56 7,476 Changes.ver0X 2006/07/02 16:56 <DIR> Jcode 2006/07/02 16:56 23,095 Jcode.pm 2006/12/16 04:28 24,289 Makefile 2006/07/02 16:56 722 Makefile.PL 2005/02/18 12:27 696 MANIFEST 2006/07/02 16:56 329 META.yml 2006/07/02 16:56 711 README 2006/07/02 16:56 <DIR> t 2006/07/02 16:56 <DIR> Unicode これらのファイルのうち、 Jcode.pm Jcode/Constants.pm Jocde/H2Z.pm Jcode/Nihongo.pod Jcode/Tr.pm Jocde/_Classic.pm Jcode/Unicode/Constants.pm Jcode/Unicode/NoXS.pm を、これらのディレクトリ構成を生かしたまま、サーバーに転送してください。 お勧めは、*.cgiファイルのあるディレクトリと同じところにJcode.pm を、 その他のものをその下の Jcode/ というディレクトリ以下にするのが手間がかからないです。 インストールはこれで終わりです。 つぎにcgiスクリプトのほうを修正します。 まずスクリプトの先頭のほうで use Jcode; とします。 SJIS から UTF-8への変換は $sjis にSJISでのデータがあるとして $utf8 = jcode($sjis)->utf8: で、$utf8に変換された結果が得られます。 ほかにも色々使い方があるのですが、とりあえずこれだけ使えれば 最低限の用は足せるだろうと思います。

MKNET
質問者

お礼

有難うございます。おかげ様で完成させることができました。ご丁寧にご指導いただき感謝いたします。

その他の回答 (4)

  • sakusaker7
  • ベストアンサー率62% (800/1280)
回答No.4

ああ、5.6ですか。じゃあ use Encodeはできなくて当然ですね。 であればJcode.pm等のモジュールをインストールする必要があるのですが、 シェルが使えるのか使えないのかで手順等変わりますのであらかじめお聞きしました。 また、シェルが使えなくてもなんとかできないこともありません。 詳しい場所とかは書けませんが、そういう環境でJcode.pmを インストールして使っていますので。 次の手順ですが、 http://search.cpan.org/CPAN/authors/id/D/DA/DANKOGAI/Jcode-2.06.tar.gz から、Jcode-2.06.tar.gz をダウンロードして、サーバーにアップロードしてください。 そうしたら、 tar xfvz Jcode-2.06.tar.gz でアーカイブをといて、 cd Jcode-2.06 ディレクトリを移ったら perl Makefile.PL INST_LIB=モジュールを置くディレクトリ を実行してください。ここでINST_LIBに指定するのはたとえば /home/userhoge/public_html/cgi-bin/lib のようなディレクトリです。指定しないとシステム共通のディレクトリに インストールに行ってしまうので多分まずいです。 この例ではCGIを置くところ(cgi-bin)の下にlibというディレクトリを掘って そこにしています。 上記のコマンドを実行すると Makefileができていますので、 make make test make intall でインストールできます。 とりあえずここまでできるかやってみてください。 シェルでの作業をしたくない場合には補足で言ってくだされば その手順を改めて説明します。

MKNET
質問者

補足

ありがとうございます。 大変お手数をおかけして申し訳ございませんが、シェル以外の方法を説明していただけると大変有難いです。宜しくお願いいたします。

  • sakusaker7
  • ベストアンサー率62% (800/1280)
回答No.3

ログを見るなどできるのであれば、本当のエラーが何なのかを確かめてみてもらいたいのですが、 多分、@INCに登録されているディレクトリで Encode.pmが見つからなかったというものでしょう。 とりあえずShiftJIS→UTF-8への変換をするのであれば、 Unicode::Japanese http://search.cpan.org/~hio/Unicode-Japanese-0.38/lib/Unicode/Japanese.pm Jcode.pm http://search.cpan.org/~dankogai/Jcode-2.06/Jcode.pm といったモジュールでも行うことができます。 これらはダウンロードしてきてインストールする必要がありますが シェルを使うことは可能なんでしたっけ? シェルが使えなくてもなんとかできなくはありませんが。 とりあえず、 ・サーバー上のシェルを使うことができるか ・サーバーにインストールされているPerlのバージョン を教えていただけますか? Perlのバージョンは Perlの特殊変数 $] の値を出力するCGIでも作って 確かめてください。

MKNET
質問者

お礼

ありがとうございます。 先ほど調べてみましたところ、 Perlのバージョンはperl version: 5.006001 (5.6.1) でした。 シェルは使えるようですが、使えるコマンドにかなりの制限があるそうです。そして私自信、シェルを使ったことがありませんので、出来るならスクリプトのみでUTF-8に変換できれば嬉しいのですが、このPerlのバージョンではシェルを使わないと無理なことなのでしょうか。

  • sakusaker7
  • ベストアンサー率62% (800/1280)
回答No.2

再度確認なんですが、質問に貼り付けてあるスクリプトはInternal Error に ならずに実行できているんでしょうか? 申し訳ありませんが、わたしはxrea.comの事情はわかりませんので、 Encode.pmの使用に関して制限があるなどの情報はもっていません。 Perlのバージョンが 5.8.0 以降であれば、標準モジュールなので 某大手プロバイダのように標準モジュールすらインストールしていないので なければ問題なく使えると思うのですが。

MKNET
質問者

お礼

はい。上記スクリプトは正常に動作しております。 他の配布されているいろいろなスクリプトでも試してみましたが、 use Encode; や、 Encode::from_to($f_data1, 'sjis', 'utf-8'); #追加 Encode::from_to($f_data4, 'sjis', 'utf-8'); #追加 を記入するとエラー表示になってしまいます。 他に、UTF-8に変換する方法はないでしょうか。

MKNET
質問者

補足

perl version: 5.006001 (5.6.1) CGI: 3.05 Jcode: 0.88 NOMODULE: not available requre 'jcode.pl': OK スクリプトを使ってPerlのバージョンを調べてみました。

  • sakusaker7
  • ベストアンサー率62% (800/1280)
回答No.1

提示されたスクリプトではUTF-8への変換をしていませんが、この状態で Internal Server Error (ですよね?)になるのでしょうか? それともUTF-8への変換を入れようとしたところでエラーが起きるようになったのでしょうか? 文字コード変換に使えるモジュールはいくつかありますが、 Perl 5.8.0以降標準でついている Encode.pmを使うのなら、 $f_data1 =~ s/ //g; Encode::from_to($f_data1, 'sjis', 'utf-8'); #追加 Encode::from_to($f_data4, 'sjis', 'utf-8'); #追加 print "$f_data1階 $f_data4\n"; のようにやればよいのではないでしょうか。 実際に使うときにはスクリプトの前のほうで use Encode; をしておくのをお忘れなく。

MKNET
質問者

お礼

ご回答ありがとうございます。教えていただいた通りに記入しましたが、やはりエラーになっていまいます。use Encode;を何処に書いてもエラーになります。 サーバはxreaを利用していますが、このサーバーではutf-8で書き出すことは不可能なのでしょうか。

関連するQ&A

  • 指定行に書込み

    open( IN, "log.cgi" ); @f_data = <IN>; close( IN ); $i = '1'; open( OUT, ">dat.cgi" ); select OUT; print "document.open();\n"; print "document.write('"; foreach( @f_data ){ if( $i > 5 ){ last; } ( $f_data1, $f_data2, $f_data3, $f_data4 ) = split( /<>/ ); $f_data1 =~ s/ //g; print "$f_data1"; $i++; } print "');\n"; print "document.close();\n"; select STDOUT; close( OUT ); 上記スクリプトで、指定された行数、又は指定された場所でdat.cgiに 書き出したいのですが、どのように書けばよろしいのでしょうか? 例えば、 ・100行目に書き出す。 または、 ・指定された文字列の間に書き出す。 (例)<!--開始-->ここに書き出す。<!--終了--> このどちらかが出来ればいいのですが、上記スクリプトをどのように変更すれば可能になるでしょうか?お手数ですが、どうぞ宜しくお願いいたします。

    • ベストアンサー
    • Perl
  • 全行読み込むには

    open( IN, "pass.dat" ) or die "Can't open pass.dat: $!"; $f_data = <IN>; close( IN ) or die "Can't close pass.dat: $!"; $f_data1 = $f_data; $f_data2 = $f_data; $f_data1 =~ s/<br>//g; $f_data2 =~ s/\S//g; open( OUT, ">log.dat" ) or die "Can't open log.dat: $!"; select OUT; print "$f_data1"; print "$f_data2"; select STDOUT; close( OUT ) or die "Can't close word.js: $!"; 上記スクリプトでは、pass.datの一行目しか読み込まれません。全行を読み込むためにはどのように書き換えればいいのでしょうか?宜しくお願いします。

    • ベストアンサー
    • Perl
  • 文字コードの変換(Shift-JISからUTF8)

    文字コードがShift-JISのCSVファイルを読み込み、UTF-8のテキストファイルに出力するのに プログラムの中で変更しようとしているのですが、うまくいきません。出力ファイルの文字コードを 確認するとShift-JISのままです。 どなたか教えていただけないでしょうか? ActivePerl v5.16.0を使用し、Encodeモジュールのfrom_toを使用しています。 #!/usr/bin/perl use strict; use warnings; use utf8; use Encode; my $input_file="input.csv"; my $output_file="output.txt"; open (IN, $input_file) or die "$!"; open (OUT, ">$output_file") or die "$!"; while (<IN>){ chomp ($_); my @data=split(/,/,$_); for(my $i=0;$i<@data;$i++){ $data[$i]=Encode::from_to($data[$i],'shiftjis','utf8'); #Shift-JISからUTF-8に変換 $data[$i]=~s/\s+//g; print OUT $_; } print OUT "\n"; } close (IN); close (OUT);

    • ベストアンサー
    • Perl
  • ログの一部を消す Perl

    ログの一部を消すPerlを考えています。 ここではソースを短くするために、ログの一部を消し去って ログファイルに上書きするデータは $deta だけだとすると open F, '+<a.log'; flock F,2; $deta = <F>;//実際はここでもっと処理 truncate F,0; seek F,0,0; print F $deta; close F; と、 open IN, 'a.log'; flock IN,2; open OUT, '>a.log'; flock OUT,2; $deta = <IN>;//実際はここでもっと処理 print OUT $deta; close OUT; close IN; の2つを考えました。 上のように 読み込み と 書き込み を同時にやった方がいいのか 下のように分けてやった方がいいのか教えてください。 ロックは flock を使って、普通レベルのロックが できるぐらいでいいと思っているんだけど、 この flock の書き方でおかしいところがあれば 教えてください。

    • ベストアンサー
    • CGI
  • ログを新しい順に保存

    始めまして。お世話になります。 初心者ですがどうぞよろしくお願いします。 cgiでメールフォームを作成しており、ログをテキスト形式で保存するように設定しています。 ログ自体は正しく保存できるのですが、 新しい順にログを保存する方法を参考書を元に以下の通り記述したのですが、新しい順になりません。 open OUT,">> log.txt"; print OUT $data,"\n"; close OUT; open IN,"log.txt"; @txt = <IN>; @txt = reverse @txt; close IN; どこを変更すればよいのかアドバイスをいただけませんでしょうか。 よろしくお願いします。

    • ベストアンサー
    • CGI
  • ログファイルの指定行に書込み

    open(IN,"$log") || &error("Open Error"); @data = <IN>; close(IN); while (100 <= @data) { pop(@data); } open(OUT,">$log") || &error("Write Error"); print OUT "$in{'id'}<>$in{'comment'}\n"; print OUT @data; close(OUT); ログにはID、時間、コメントが登録されています。 送信データの中に、ログに登録済みのIDがある場合には、そのIDのある行のみを書き換えたいのですが、方法がどうしてもわかりません。 $logに記録されるIDの順番は以下のようにランダムです。IDに登録される文字列は1からの数値のみです。 52<>コメント 120<>コメント 35<>コメント 8<>コメント 2<>コメント 19<>コメント 85<>コメント よろしくお願いいたします。

    • ベストアンサー
    • Perl
  • CGIを作動させてサーバにかかる負担の問題

    CSVデータを開き、ソートして別のCSVを書き出す というCGIを設置する必要が生じています。 そこで、 open(INFILE,"test_sort_data.csv"); @Read_In = <INFILE>; close(INFILE); @Read_In2 = sort { (split(/\,/,$a))[0] <=> (split(/\,/,$b))[0] } @Read_In; open(OUTFILE,">test_sort_data1.csv"); for($i=0 ; $i<=$#Read_In2 ; $i++){ print OUTFILE "$Read_In2[$i]" ; } close(OUTFILE); というスクリプト(実際は更に改造して、このCGIを使って元CSVにソート基準になる短い文字列を1項目書き加えるためのルーチンを加えます)のCGIを動かしたいのですが、この方法はサーバのメモリを消費する可能性がありますので、行数の多いデータには注意が必要とのことです。 開こうとしているCSVは、1行あたり6項目、カンマを合わせて100文字程度になると思われ、行数は最大20,000行くらいになると思われます。 これを、さくらインターネットのレンタルサーバのスタンダードプランで動かすのはまずいでしょうか? もし問題がある場合、何か対策は無いでしょうか? PCにフリーウェアなどをインストールしたりExcel上でデータをいじることの出来ないリモート中の上司に使ってもらうためなので、Webを介して数ステップのクリック程度で作業を完了してもらわないとならないのですが… ご教示いただけないでしょうか? どうかよろしくお願い致します。

  • 連続投票の制限

    投票cgiを設置したいのですがうまくいきません、集計を1日一回だったのを少し改造して即時集計にしました 一応動くのですが、連続投票できてしまいます。 連続投票を一定時間制限できるようにしたいのですがうまくいきません 60秒くらい間をおいてから投票できるようにできますか? ip制限もあるみたいなのですがこれも機能してないです・・・ 改善できるなら元のソースがかなり変わってもかまいません 連続投票制限だけでも機能できればと思っています。よろしくお願いします local $times = time(); sub vote{ if($FORM{id}){ my $fl=0; if(!$CK_ref){$fl=1;} else{ if(index($ENV{'HTTP_REFERER'},index.html>=0){$fl=1;} } if($fl){ $FORM{id}=~s/\n//g; my $vote = $FORM{vt2}?1:0; open(OUT,">>vote_temp.cgi"); #時間用のログファイルに書き込み print OUT "$FORM{id}<>$ENV{'REMOTE_ADDR'}<>$FORM{vt}<>$vote<>".$times."<>\n"; close(OUT); &reset_vote if $VT_RESET < $times; my(@log_lines,%pt,%pt2,%cnt,$name,$value,%CKIP); open(IN,"vote_temp.cgi"); my @log = <IN>; close(IN); if(@log){ my $cktime = $times - 60; #60秒制限 open(IN,"vote_ck_IP.cgi"); #投票した人のIPを記録したログ while(<IN>){ my @ck = split('<>'); next if $_[1] < $cktime; $CKIP{$_[0]} = $_[1]; } close(IN); foreach(@log){ chop; my @rank = split('<>'); #ID<>IP<>評価<>おすすめ<>時間\n next if $CKIP{"$rank[0]_$rank[1]"}; $pt{$rank[0].'_'.$rank[2]}++; $pt2{$rank[0]}++ if $rank[3]; $cnt{$rank[0]}++; $CKIP{"$rank[0]_$rank[1]"} = $rank[4]; } open(OUT,">vote_temp.cgi"); close(OUT); open(OUT,">vote_ck_IP.cgi"); while(($name, $value) = each(%CKIP)){ print OUT "$name<>$value<>\n"; } close(OUT); open(IN,"log.cgi"); my @data = <IN>; close(IN); foreach(@data){ #集計処理長かったので省略 } open(OUT,">vote_bf.cgi"); open(IN,"vote_log.cgi"); while(<IN>){ print OUT $_; } close(IN); close(OUT); open(OUT,">vote_log.cgi"); print OUT @log_lines; print OUT "\n1;\n"; close(OUT); } &make_vote_ck('set'); } } sub reset_vote{ my @log; foreach my $i(1..$LAST_ID){ next if !@{$VT[$i]}; $VT[$i][18] = $VT[$i][7]; $VT[$i][19] = $VT[$i][8]; $VT[$i][20] = $VT[$i][0]; foreach my $j(0..8){ $VT[$i][$j] = 0; } push(@log,'$VT['.$i.'] = ['.(join(',',@{$VT[$i]}))."];\n"); } open(OUT,">vote_log.cgi"); print OUT @log; print OUT "\n1;\n"; close(OUT); &make_vote_ck('reset'); } sub make_vote_ck{ if($_[0] eq 'set'){ my @t =localtime($times + 86400); $VT_TIME = timelocal(0,0,5,$t[3],$t[4],$t[5]); $VT_RANK = $VT_RUI = $VT_RECO = $VT_RCRUI = $VT_COUNT = $VT_CTRUI = $VRK_CK = 1; } if($_[0] eq 'reset'){ my @m =localtime($times); $m[4] += 1; if($m[4] > 12){ $m[4] = 1; $m[5] += 1; } $VT_RESET = timelocal(0,0,2,1,$m[4],$m[5]); $VT_RANK = $VT_RECO = $VRK_RS = $VRK_CK = 1; } if($_[0] eq 'restore'){ $VT_RANK = $VT_RUI = $VT_RCRUI = $VT_RECO = $VT_COUNT = $VT_CTRUI = $VRK_CK = 1; } open(OUT,">vote_ck.cgi"); print OUT "\$VT_TIME = '".$VT_TIME. "';\n"; print OUT "\$VT_RESET = '".$VT_RESET. "';\n"; print OUT "\$VT_RANK = '".$VT_RANK. "';\n"; print OUT "\$VT_RUI = '".$VT_RUI. "';\n"; print OUT "\$VT_RECO = '".$VT_RECO. "';\n"; print OUT "\$VT_RCRUI = '".$VT_RCRUI. "';\n"; print OUT "\$VT_COUNT = '".$VT_COUNT. "';\n"; print OUT "\$VT_CTRUI = '".$VT_CTRUI. "';\n"; print OUT "\$VRK_CK = '".$VRK_CK. "';\n"; print OUT "\$VRK_RS = '".$VRK_RS. "';\n"; print OUT "\$LAST_ID = '".$LAST_ID. "';\n"; print OUT "\n1;\n"; close(OUT); }

    • ベストアンサー
    • Perl
  • IF文について

    こんにちは。 フリーのチャットのperlで書かれたCGIを見ていて、以下のようなIF文が ありました。 これってどういう意味なのですか? if(! -f $log) { open(OUT,">$log"); close(OUT); } よろしくお願いします。

    • ベストアンサー
    • CGI
  • 配列のデータから改行だけを取り除いて上書きしたい

    いつもお世話になっています。 CGIで現在下記のようなファイルがあります。 【sample.cgi】 1<>2<>3<>4<>5<> 6<>7<> これを下記のスクリプトで呼び出し配列に入れます。open(IN,"./sample.cgi"); @DATA = <IN>; close(IN); @data = split(/<>/,$DATA[0]); @N_DATA=(); unshift(@N_DATA,"$data[1]<>$data[2]<>$data[3]<>$data[4]<>$data[5]<>$data[6]<>$data[7]<>"); open(OUT,">./sample.cgi") or &error('書き込み失敗'); print OUT @N_DATA; close(OUT); しかし実行結果は改行が残ったままで、どうにか 1<>2<>3<>4<>5<>6<>7<> という形で出力したいのですがどのように変更を行えば宜しいでしょうか。 恐らく「unshift」の部分が行を追加していっていると思うのですが、printなどで出力するとsample.cgiの中身が空になってしまい・・・。 「読み込むデータに改行があった場合は改行を削除して読み込む」という動作をさせたいのですが・・・。 何卒よろしくお願い致します。

    • ベストアンサー
    • CGI

専門家に質問してみよう