トップページ⇒php
1001コメント315KB

Perl コーディング初心者質問コーナー Part25

■ このスレッドは過去ログ倉庫に格納されています
0001nobodyさん03/06/28 01:18ID:???
いらっしゃーい、Perlのコーディングで困ってる人のスレです。

【投稿する際の注意】
質問するときは内容をよく吟味してから投稿してください。

1:自分はこう言う事がしたい。
2:それでこんな風にやってみたが・・・
3:こんなエラーが出て上手く行かなかった。

最低でも1と3が無いと誰も答えられないよ。
ソース貼る時は、全角スペースでインデント忘れずに。
良い回答は良い質問から。一緒に勉強しましょう。

関連スレ
【Perl上級者コーナーPart01】
http://pc2.2ch.net/test/read.cgi/php/1024741312/
CGI: Common Gateway Interface part 11
http://pc2.2ch.net/test/read.cgi/php/1055597189/
【Perl,CGI】参考書籍 第三版
http://pc2.2ch.net/test/read.cgi/php/1030209573/
【 スクリプト改造工房 PART 6 】
http://pc2.2ch.net/test/read.cgi/php/1047806915/

過去ログやお勧めサイトは >>2-10
0196nobodyさん03/07/03 14:34ID:???
漏れもゴッホのひまわりをperlに変換するのはいくつか書いた
0197nobodyさん03/07/03 14:37ID:???
漏れも >>191-193 を >>194 に変換するのはいくつか書いた
0198nobodyさん03/07/03 14:39ID:???
>>194
確かに、ネタにそこまでマジレスできる君と俺とでは
かなりレベルが違うようだ。
0199nobodyさん03/07/03 14:39ID:???
>>194
それってASPとかじゃなくてクライアントサイドってことだよな?
だとするとアクセスできないディレクトリに置いたら動かないだろw

で、クライアントサイドとサーバサイドじゃ処理が違うのに変換???w
0200nobodyさん03/07/03 14:40ID:???
俺もダンディ坂野のギャグをPerlに変換するのはいくつか書いた。
0201nobodyさん03/07/03 14:41ID:???
>>199
きっと俺らちとはレベルが違んだよ(w
0202nobodyさん03/07/03 14:43ID:???
俺もパチンコ玉を真珠に変換するのはいくつか書いた
0203nobodyさん03/07/03 14:44ID:???
漏れもマスならカイた
0204nobodyさん03/07/03 14:46ID:???
プロフェッショナルってすごいなぁ。
僕もがんばります!!
0205nobodyさん03/07/03 14:49ID:???
漏れも金と銀をパールに変換してプレゼントした
0206nobodyさん03/07/03 14:54ID:???
俺もPerlをドラクエ風に変換するのはいくつか書いた。
0207nobodyさん03/07/03 15:01ID:???
漏れも、とても綺麗な真珠だね、もっと綺麗な牧シンジュ!
だけどお前の頭の中は、シンジュじゃ無くてPerlだよ、なら書いた
0208nobodyさん03/07/03 15:08ID:Ctng5Cwy
>>195
perl -pe 'chop; $_="print `\Q$_\E`;\n"'
020910703/07/03 15:39ID:???
作ってみました。
#!/perl/bin/perl
use Net::Ping;
#適当なネットワークIP
$host = "210.***.***.***";
#IPを数えるカウント
$count = 0;
($sec, $min, $hou, $day, $mon, $yea, $wek) = localtime();
$yea=$yea+1900;
$mon=$mon+1;
while (1) {
if (pingecho($host, 5)) {
$count=0;
print "$yea/$mon/$day $hou:$min:$sec Count:$count IP:$host is alive.\n";
}else{
$count++;
print "$yea/$mon/$day $hou:$min:$sec Count:$count IP:$host is no return.\n";
}

if ($count > 3) {
print "$yea/$mon/$day $hou:$min:$sec Count:$count IP:$host is dead.\n";
last;
}
sleep(5);
}
while (1) {
print "モデムが停止しましたー\a\n";
sleep(1);
}
021020903/07/03 16:00ID:???
ログの時間が動いていないことが今判明したTT
0211nobodyさん03/07/03 16:05ID:Ctng5Cwy
>>209
その「適当なネットワークIP」って、他人のリソースじゃないだろうな?

Pingは負荷が大きいから、回線の生死にPingを打つのは問題ありだと
思うんだけど。LAN中ならいいけど、外に出すのはマナー上良くないと
思われる。

もし俺がネットワーク管理者で、どっかのクライアントからPingが垂れ流されて
きたら、いたずらか攻撃だと判断してフィルターかけるよ。
0212あぼーんNGNG
あぼーん
0213nobodyさん03/07/03 16:30ID:???
>>211
Net::Pingは、デフォルトでTCPのECHOにConnectするようになってるよ。
ICMP(いわゆるPing)は指定しないと使わない。
まあどのみち他人のホストを回線チェックに使うのは感心しないけど。
0214nobodyさん03/07/03 17:13ID:83sptUFL
$value =~ tr/0-9/0-9/;
print $value;

HTMLの見栄え表示用に半角数字を全角数字に置き換えを行っていますが
文字化けします。元は一桁か二桁の半角数字です。
座、とか抗とか、、、

$value =~ tr/0-9/a-j/;

だと上手くいきます。
コードはEUC-JPで書いてます。
日本語処理の問題だと思うのですがいろいろ調べてみてもわかりませんでした。
ちなみに日本語関係はJcode.pm使えます。

どなたか教えて下さい
0215nobodyさん03/07/03 17:27ID:???
>>214
jperlでない限り、tr///は2バイト文字をサポートしていません。
したがって、>>214のtr文は、

・0の1バイト目
・0の2バイト目〜9の1バイト目
・9の2バイト目

が指定されたように受け取ります。Jcode.pmを使っているのなら、

jcode($value)->tr('0-9', '0-9');

を試してみてください。
0216nobodyさん03/07/03 17:29ID:???
>>215
>jperlでない限り、tr///は2バイト文字をサポートしていません。
これちょっと嘘だったかも。
0217nobodyさん03/07/03 17:32ID:???
>>214
$value =~ s/0/0/g;
$value =~ s/1/1/g;
$value =~ s/2/2/g;
$value =~ s/3/3/g;
$value =~ s/4/4/g;
$value =~ s/5/5/g;
$value =~ s/6/6/g;
$value =~ s/7/7/g;
$value =~ s/8/8/g;
$value =~ s/9/9/g;

(w
021821403/07/03 17:41ID:???
>>215

早速ありがとうございました。
御指摘の方法で上手くいきました。
0219nobodyさん03/07/03 17:42ID:???
>>214
$value =~ s/([0-9])/('0','1','2','3','4','5','6','7','8','9')[$1]/eg;
つぅのはどうでしょう?
022021503/07/03 17:50ID:???
>>217>>219
それだったら

$value =~ s/([0-9])/pack("c2", 0xa3, 0xb0+$1)/eg;

の方が良くないか?
0221nobodyさん03/07/03 19:19ID:???
>>214はテンプレ見てねーな
漏れもヘタレだけど、リンク先たどれば解決策はザクザク出るのに
0222 ◆hMJAPH9PWA 03/07/03 20:22ID:???
>>220
文字コードに依存するやりかたは良くないと思う。
0223nobodyさん03/07/03 20:28ID:Ctng5Cwy
>>222
その直前で$valueをEUCに変換してるという前提だから別に構わないでしょ。
>>217や219だってISO-2022-JPでやれば一発でエラー(or文字化け)がでるわけで。
0224nobodyさん03/07/03 20:36ID:???
アルファベットを一旦全部大文字にしてから処理、とかの
常套手段と同様に、
EUCに揃えてから好きに加工、というのは
普通にアリだな
0225nobodyさん03/07/03 21:16ID:???
ところで「日」と「曰」の区別できるようになったの?>えうC
0226nobodyさん03/07/03 21:52ID:???
大と丈の区別は付くようになりました。
0227 ◆hMJAPH9PWA 03/07/03 22:52ID:???
>>223
あー、変換してからか。スマソ。

それでも個人的にはわかりやすいほうが良いな。
0228nobodyさん03/07/03 23:25ID:z1S7djbc
217でいいんだよ
0229あぼーんNGNG
あぼーん
0230nobodyさん03/07/04 11:23ID:???
ブラクラ注意
0231nobodyさん03/07/04 12:28ID:???
./tmp ディレクトリにあるファイルを全て削除するにはどうすればいいのでしょうか?
0232nobodyさん03/07/04 12:32ID:???
>>227>>228
分かりやすさを採るか効率を採るかだと思うけど、
>>217は効率悪すぎ。

>>231
unlink <./tmp/*>;
0233nobodyさん03/07/04 13:01ID:???
>>217はネタでしょ?
0234nobodyさん03/07/04 13:04ID:???
このスレも盛り上がらなくなったな・・・。おまえら書けよ。
0235nobodyさん03/07/04 13:05ID:???
>>233
ネタだと思いたいが、仕事で他人のコードを見る機会が多いと、
>>217が可愛く見えるくらいの想像を絶するコードに度々遭遇する。
0236nobodyさん03/07/04 13:10ID:???
文字コード直接書くような糞コードよりはましだろ。。。
0237nobodyさん03/07/04 13:31ID:???
なんかお題になるようなものないかな
023823103/07/04 13:34ID:???
>>232
unlink <./tmp/*>; やっても消えません。エラーメッセージもでません。
どうすればいいのでしょう?
0239nobodyさん03/07/04 13:40ID:???
意識が朦朧としてるとな、
エレガントな方法よりも確実に間違わない方法を
取ったりするんだ
どうせ後で直すけどな
0240nobodyさん03/07/04 13:41ID:???
>>238
tmpの1階層上で実行したか?
024123103/07/04 14:02ID:???
>>240
はい、もちろん。
lsすると
tmp.cgi
tmp
って感じになります。(実際はシェルを開放してませんが)

うち、lsとかのコマンドをcgiから実行できないようなんですが、
それって関係あります?
0242nobodyさん03/07/04 15:49ID:???
>>236
Cだと普通に使われる手法だと思うけどな>直接文字コード
まぁ↓のようにしたって構わない訳だが。

my(@zero) = unpack("C2", "0");
$value =~ s/([0-9])/pack("C2", $zero[0], $zero[1]+$1)/eg;

>>241
パーミッションの問題じゃないのか?ファイルの所有者と
CGIスクリプトの実行者が違うとか。
0243nobodyさん03/07/04 16:20ID:???
>>242
Cじゃなおさらそんなことしないよ・・・・
0244nobodyさん03/07/04 18:51ID:???
unlink <./tmp/*> or die $!;
で見てみれば?
024523103/07/04 19:16ID:???
>>244
unlink <./tmp/*> or die $!;
したら、500 Internal Server Error になってしまいましいた。
アパッチのエラーログは、

glob failed (child exited with status 127) at tmp.cgi line 2.
Died at tmp.cgi line 2.
[Fri Jul 4 19:14:46 2003] [error] [client xxx.xxx.xxx.xxx] Premature end of script headers: /ここ略してます/tmp.cgi
とでました。

tmp.cgiの中身は、
------------------------------------------------------------
#!/usr/local/bin/perl
unlink <./tmp/*> or die $!;
print "Content-type: text/html\n\n";
print "これはテスト";
------------------------------------------------------------
です
0246nobodyさん03/07/04 19:20ID:???
ヘッダ出す前に死んでどうすんだよ。
#!/usr/local/bin/perl
print "Content-type: text/plain\n\n";
unlink <./tmp/*> or die $!;
print "これはテスト";
0247nobodyさん03/07/04 22:03ID:???
>>245
ワロタ
0248nobodyさん03/07/04 22:05ID:???
>>245

>>246 で言われた事を修正して実行してみてそれでも解らなければ、
eval して $@ をチェッくらいとすればいい
0249nobodyさん03/07/04 22:27ID:???
>>246>>248
エラーメッセージの内容くらい見ようよ。

>>245
> glob failed (child exited with status 127) at tmp.cgi line 2.

globに失敗してる。cshが使えない環境か、cshがglobに使う
一時領域にアクセスできないのが原因だと思う。
素直にglobは諦めて

opendir(DIR, "./tmp");
unlink (grep !/^./, readdir DIR);

とかした方が良いかも知れない。
0250nobodyさん03/07/05 00:36ID:???
MLDBMを使おうとしています。

$database{"$id"} = %params;
で格納し、

foreach my $id ( keys %database ) {
print qq($id <BR>);
foreach my $key (keys %{ $database{$id} }){
print qq($key <BR>);
print qq($database{$id}{$key} <BR>);
}
}
で中身を確認しようとしていますが1個目の$idで表示が止まります。
$idは四つあり、%paramsのkeyは15個ほどあります。

foreach my $id ( keys %database ) {
print qq($id <BR>);
}
と、$idのみを全て見ようとすると三つとも表示されます。
入門 perl DBI を見て、
print Data::Dumper->Dump( [ \%database ] );
しましたが、
$VAR1 = { '2003415' => '1234 2003 game_year', '20031010' => '24/64', '20030606' => '18/32', '20030505' => '18/32' };
こんな表示です。。。。

2003415 20031010 20030606 20030505 は%databaseのkeyで、
あとは%paramsのkeyやらvalueやらの一部ですが全部じゃありません。

MLDBM初めて使うので、とりあえず格納して、それを表示させて
確かめる為のテストをしているのですが、
%{ $database{$$id} }のkeyとvalueを表示させるにはどうしたらいいのでしょうか。
025125003/07/05 00:37ID:???
>>250
> 三つとも表示されます。
は四つとも表示されます、の間違いです。
0252nobodyさん03/07/05 01:24ID:???
>>250
$database{$id} = \%params;
こうだろ?
リファレンスの基礎からやりなおしてこいよ。

0253nobodyさん03/07/05 02:00ID:???
基礎ができない(or 解らない)から、ここにカキコするんじゃねーの?
その為の初心者スレだと思うが…。流石に釣りやネタには俺はレスしないけどな
0254nobodyさん03/07/05 03:29ID:???
基礎的なことにつまずくのはしょうがないよ。
そうやって一歩ずつ覚えていけばいいんだから。ただ、

  エラーメッセージは読め。
  英文だろうがなんだろうががんばって読め。
0255nobodyさん03/07/05 03:43ID:???
そういうことだね。
英文のメッセージが読めないなら和訳のを探せばいいのに。

ttp://www.namazu.org/~tsuchiya/perl/info/perl-ja_109.html
0256252じゃないが03/07/05 12:13ID:???
コーディング上の質問は>>252で解決したわけだ。
質問の本質が「リファレンスを理解してない」という事にあるので、それを指摘するのが何故悪い?
0257nobodyさん03/07/05 17:21ID:jB+j5VLT
print <<ENDDOC;
 ・・・
ENDDOC

でENDDOCが見つからないと怒られるんですが
何か他にやらなければいけないことがあるんでしょうか?
0258nobodyさん03/07/05 17:23ID:???
>>257
ENDDOCのあとに空白がある。
print <<ENDDOC;
 ・・・
ENDDOC ←ここ
0259nobodyさん03/07/05 17:52ID:???
それはコピペの特性では
026025703/07/05 17:58ID:???
ソースでは入ってないです。
コピペしたわけでもないのですが・・謎

というかどの行も全部そういう風になってますね(^^;
026125703/07/05 18:09ID:???
わかりました!
先頭にタブ入れちゃいけないんですね。
後ろに付いちゃいけないという事は
前にも付いちゃいけないのかと思ってやってみたら。

参考書の
print <<" AAA"
の先頭の空白の意味がわかった・・・

どうもでした>258さん
0262nobodyさん03/07/06 02:53ID:???
質問です。

eval{ flock(FILE,2); };
if($@){ &MkDIR ; }

これは期待通りに動きますか?
026326203/07/06 03:01ID:t//EFERU
age 忘れでした。
0264nobodyさん03/07/06 03:59ID:???
>>262
どういう結果を期待してるのか分からんが、
とりあえずエラーは起きないだろう。
026525003/07/06 09:49ID:1R/hd8rn
>>252
アドバイスありがとうござました。
リファレンス、どうも今一理解していないようです。
何しろプログラム自体ちゃんと勉強したものじゃないもので、
どうしても書くものがフラットになりがちなのですが、ちょっと複雑なものを
strictに書こうとすると避けて通れないですよね。

本はもっぱらオライリーのものを、初めての〜とかプログラミングperlとか
CGIプログラミング、あと関係ないですけどjava scriptとか読んでますが、
なかなか奥が深いですよね。

僕としては大物で(僕にとってはですが)一から作った二つ目ですが、
アドバイスのおかげで何とかものになりそうで、ほっとしました。

クックブック欲しいなあと思ってますが、実用perl〜、は僕には難しすぎるでしょうか。
0266nobodyさん03/07/06 12:46ID:???
>>265
その前にEffective Perl読んでおいたほうがいいと思うよ。
自信をもってプログラムを書けるようになる。安いし。
0267nobodyさん03/07/06 19:04ID:AvDpfWTI
文字列を入力してweb上のテキストファイルにアクセスして検索し、
何行目にあるかを表示したいのですがうまくいきません
$name = $in{'name'};
&jcode'convert(*name,"sjis");
if(!open(OUT,"$file")){&error(err_file);}
flock(OUT,2);
@DATA = <OUT>;
flock(OUT,8);
close(OUT);
$count = @DATA;
$i = 0;
$found = -1;
while($i<$count){
($chk[$i]) = split(/\,/,$DATA[$i]);
if($chk[$i] eq $name){
$found = $i;
}
$i ++;
}
こうしたのですが該当するものを入力してテストしてみたのですが
全部 -1 になってしまうのですがどうしたらいいのでしょうか?
テキストファイルはこういう感じです。読み込みは出来ています。
データ1
データ2
データ3
・
・
・
0268nobodyさん03/07/06 19:08ID:???
>>267
($chk[$i]) = split(/\,/,$DATA[$i]);
何がしたいんだ、ここんところ。
この行について自分の言葉で自分の意図するところを明確に書きなさい。
そしたら多分、解決できるから。
0269nobodyさん03/07/06 19:11ID:???
flockするタイミングおかしくない?
027026703/07/06 19:11ID:AvDpfWTI
すみません覚えたてなので変な書き方してるかもしれません。。
$chkに$i行目のデータを$nameと比較するために読み込んで格納している
つもりなのですが・・
0271nobodyさん03/07/06 19:14ID:???
$chk[$i]をprintして、何が入っているか確認すれば原因わかりそう
027226703/07/06 19:21ID:AvDpfWTI
>>271
whileのあとにprintしてみたら表示できるのですが
whileの中でprintしたらエラーになってしまいました・・
027326703/07/06 19:25ID:AvDpfWTI
printはなんとかできました。
テキストファイルの中身が全部読み込まれて表示はされました。
でも検索結果だけが出ません・・-1のままです。
027426703/07/06 19:45ID:AvDpfWTI
$count = @DATA;
$i = 0;
$found = -1;

while($i<$count){
 ($chk[$i]) = ($DATA[$i]);
 print $chk[$i];
 if($chk[$i] eq $name){
  $found = $i;
 }
 $i ++;
}

今こんな感じですが $found の値が -1 です・・
0275nobodyさん03/07/06 19:50ID:???
while (<OUT>){
chop;
$_ eq $name and $found,last;
}
027627503/07/06 19:51ID:???
$_ eq $name and $found=$.,last;

まちがった
0277nobodyさん03/07/06 19:54ID:???
>>267
なんか、メチャクチャだな…。
ひょっとして @chk に見つかった行を格納したいのか?

 ち ゃ ん と 期 待 し た い 結 果 を 明 記 し て く だ さ い

で、俺ならこうする

# @chk にヒットした行番号を格納
# 検索対象は $name
# $[ を 0 と仮定する

$i = $j = 0;
foreach ( @DATA ) {
 if ( $_ eq $name ) {
  $chk[ $i++ ] == $j;
 }
 ++$j;
}
027826703/07/06 19:55ID:AvDpfWTI
>>275
ありがとうございます。それでやってみたのですがやはり -1 のままでした。。
0279nobodyさん03/07/06 20:00ID:???
まさか…。

/$name/
↑これで OK ってオチじゃねーだろーなぁ?

$_ eq $name は「完全に一致」ってこと解ってる? >>267
0280nobodyさん03/07/06 20:01ID:???
>>277 chop; 抜けてた
0281nobodyさん03/07/06 20:02ID:???
>テキストファイルの中身が全部読み込まれて表示はされました。
で、$nameが含まれてるものを知りたいんだろう?
$chk[$i] eq $name じゃなくて、マッチ演算子使うとか・・・

$KEKKA = $DATA[$i] =~ m/$name/;
028226703/07/06 20:08ID:AvDpfWTI
すみません。含むものじゃなく完全一致です。
$chkに一旦格納したものを$nameと比較して一致なら$foundに行数を格納というつもりでした。
277さんの方法でやってみてもだめでした・・
どこかおかしくて微妙に完全一致してないのかとも考えたのですがそうでもないような
気もしたりします。

ちょっと今から出かけますすみません・・・
0283nobodyさん03/07/06 20:16ID:???
テキストファイルの文字コードはどうなってる?
あと、$found はマッチした行数のことか?

# [廃止] @chk にヒットした行番号を格納
# 検索対象は $name で完全一致
# $found にはマッチした行数が入る。0ならマッチなし
# $[ を 0 と仮定する
&jcode'convert( *DATA, 'sjis' );
$found = 0;
foreach ( @DATA ) {
 chop ; # 行末の \n を削除
 ++$found if ( $_ eq $name ) ;
}
0284あぼーんNGNG
あぼーん
0285nobodyさん03/07/06 21:34ID:???
 print $chk[$i];
 if($chk[$i] eq $name){
を
 print "!$chk[$i]!=!$name!"; ←文字列の両端に何か文字入れてprint
 if($chk[$i] eq $name){

にしてやってみろ。多分分かる。
0286nobodyさん03/07/06 21:35ID:???
失敬。
 print "!$chk[$i]!=!$name!"; ←文字列の両端に何か文字入れてprint
を
 print "!$chk[$i]!=!$name!\n"; ←文字列の両端に何か文字入れてprint
に変えてくれ。
0287nobodyさん03/07/06 21:55ID:???
一旦格納するなら何も配列でやるこたぁないんじゃないのか・・・
とにかく$chk[$i]があやしいことだけは確か
0288nobodyさん03/07/07 01:00ID:???
諦めて最初から組みなおせ。
028926703/07/07 01:07ID:kYkAMaKH
今帰ってきました。今からやってみます。
029026703/07/07 01:29ID:kYkAMaKH
すみません解決しました・・
よく見たら改行が入っていました。おれの変なソースをわざわざ見ていただき
みなさんありがとうございました。

こういう風にしました
 $count = @DATA;
 $i = 0;
 $found = -1;
 while($i<$count){
  ($chk[$i]) = ($DATA[$i]);
  $chk[$i] =~ s/\n//g;
  if($chk[$i] eq $name){
   $found = $i + 1;
  }
  $i ++;
 }

かなり下手なやり方なんだろうと思いますが許してくださいごめんなさい・・
029126703/07/07 01:29ID:???
sageます・・すみません・・
0292nobodyさん03/07/07 01:31ID:???
みなのアドバイスが無駄になったということで。

↓次に質問
0293nobodyさん03/07/07 01:36ID:???
「ファイルを読んでsplit」ではよくあるトラブルではあるな>改行
0294nobodyさん03/07/07 01:38ID:???
>>292
まったくだ…。死んでくれ
0295nobodyさん03/07/07 01:40ID:???
>>267
大体、$chk って何のためのデータよ?
データをやたらコピーとかするからおかしくなったり混乱したりするんだよ。
変更しないデータならコピーして使うなよ
■ このスレッドは過去ログ倉庫に格納されています