Perl 初心者コーナー Part23
■ このスレッドは過去ログ倉庫に格納されています
0001nobodyさん
03/05/16 11:18ID:zDRBc/j4【投稿する際の注意】
質問するときは内容をよく吟味してから投稿してください。
1:自分はこう言う事がしたい。
2:それでこんな風にやってみたが・・・
3:それだとこんなエラーが出て上手く行かなかった。
最低でも1と3が無いと誰も答えられないよ。
良い回答は良い質問から。一緒に勉強しましょう。
CGIだけど、なんか質問ある? Part 10
http://pc2.2ch.net/test/read.cgi/php/1048686475/
【Perl,CGI】参考書籍 第三版
http://pc2.2ch.net/test/read.cgi/php/1030209573/
CGIに依存しないPerlの話題一般/Part2
http://pc2.2ch.net/test/read.cgi/php/1030548610/
スクリプトの改造依頼は、【 スクリプト改造工房 PART 6 】
http://pc2.2ch.net/test/read.cgi/php/1047806915/
過去ログやお勧めサイトは >>2-10
0332nobodyさん
03/05/23 16:49ID:???if(grep(/$city/,@ArrayCity)){ $Flag = 1; }
0333nobodyさん
03/05/23 17:29ID:???(わかりやすいようにチャンネルとテレビ局名を例にしてます)
@channel = (6,1,8,4,10)
@tvname = ('tbs','nhk','cx','ntv','asahi');
っていう配列があって、
これを、
@channelの要素の小さい順に、@tvnameの要素をソートすることって
どうすればできるのでしょう?
要は、
@new_tvname = ('nhk','ntv','tbs','cx','asahi');
を取得したいのですが。
0334nobodyさん
03/05/23 17:32ID:XGb65p6nキーをソートしたらいいのに・・・
0336333
03/05/23 19:55ID:???スパゲッティ状態で、連想配列に変換しようとしても、うまくいかず。。。
0338nobodyさん
03/05/23 20:39ID:???my @no = sort {$channel[$a] <=> $channel[$b]} 0 .. $#channel;
my @new_tvname = @tvname[@no];
0340nobodyさん
03/05/23 21:22ID:???こういうのはじめてみた。勉強になった。
0342nobodyさん
03/05/23 22:15ID:???@tv_table{@channel} = @tvname;
@new_tvname = map $tv_table{$_}, sort {$a <=> $b} keys %tv_table;
0343nobodyさん
03/05/23 23:01ID:???やりたい事は、メインのスクリプトからパッケージのサブルーチンへ2つの配列を参照渡しさせたいのです
テスト用に以下のスクリプトで試してみましたが、エラーとなってしまいます。
#test.cgi
#!/usr/bin/perl
use strict;
use vars qw(@test1 @test2 @output);
require 'test.pl';
@test1 = ('abc', 'def');
@test2 = ('ghi', 'jkl');
@output = &testlib::convert(*test1, *test2);
print "@output\n";
0344343
03/05/23 23:02ID:???#test.pl
package testlib;
use strict;
#use vars qw(@sub_test1 @sub_test2);
sub convert {
local (*sub_test1, *sub_test2) = @_;
my @line;
foreach (@sub_test1) {
$_ =~ s/abc/def/i;
push (@line, $_);
}
foreach (@sub_test2) {
$_ =~ s/ghi/jkl/i;
push (@line, $_);
}
return @line;
}
1;
これでstrictをコメントアウトすると問題ありませんでした。
また、strict有効状態で、パッケージ内の#use varsを有効にすると上手く行きましたが、
基本的にパッケージの方でもvarsで宣言しておかないとダメなのでしょうか?
0346345
03/05/24 00:02ID:???配列スライスは例えば($second, $third) = @array[2,3]; とかできるっす。
0347345
03/05/24 00:07ID:???0348nobodyさん
03/05/24 00:10ID:f0Btk8DHっていう列を格納しているCSVファイル(DBではないのです(泣))があるのですが、
それに対して、
「select * from orgmaster where flagplan=1 ordeby planid countryid」
した結果をはき出したいと思ってますが、とんとわかりません。
どのようにすればいいのでしょうか?
なお、DBD::CSV は使えない環境です・・・
0349nobodyさん
03/05/24 02:21ID:???# test.cgi
#!/usr/bin/perl
use strict;
use TestLib;
my @test1 = ('abc','def');
my @test2 = ('ghi','jkl');
TestLib::convert(\@test1, \@test2);
print @test1, @test2;
__END__
# TestLib.pm
package TestLib;
use strict;
sub convert {
s/abc/def/i for @{$_[0]};
s/ghi/jkl/i for @{$_[1]};
return '昆布。';
}
1;
__END__
0350nobodyさん
03/05/24 02:40ID:???>>343-344
Perl4?
Perl5ならリファレンスでいけると思うけど。
後、use varsは使わない方がいいと思う
0351nobodyさん
03/05/24 02:42ID:???0352nobodyさん
03/05/24 05:09ID:???0353343
03/05/24 08:00ID:???御指南ありがとうございます。
せっかくいただいたのですが、今は試せる時間が無いので今日の夜にでも自分トコで使ってみます。
外部にサブルーチン持たせる時はそういう使い方でしたか…
あの長ったらしい分がここまで短くなるとは、奥が深いです。
>>350
失礼しました。
環境はPerl5.008です。リファレンスというキーワードで勉強してみようと思います。
use varsは色んなperlの解説サイトで、strict宣言するときに…
みたいな事がかかれていたのですが、使わない方向で頑張ってみます。
0354nobodyさん
03/05/24 17:48ID:CEfAWsDp$file = "count.dat";
open(FILE, "+<$file");
flock(FILE,2);
$count = <FILE>;
chomp $count;
$count++;
seek(FILE,0,0);
print FILE "$count\n";
flock(FILE,8);
close(FILE);
print "location:../ip/ip.zip\n\n";
こうすると、このcgiが呼び出された回数は記録できるんですが、私はダウンロードされた数が知りたいんです。
どうすればいいですか?ダウンロードが完了したらカウントアップってのをしたいんですが・・・
0355nobodyさん
03/05/24 18:03ID:???例:
$value1 = 'http://www.yahoo.co.jp';
$value2 = 'Copyright (C) 2003 Yahoo Japan Corporation. All Rights Reserved. ';
この場合、$value1 と $value2 には大文字小文字の違いはありますが、yahooの文字列が両方ともに存在します。
このように、$value1 と $value2 を比較して、なかに同じ文字列が存在する場合に真とすることって可能なのでしょうか?
例ではyahooが同じ文字列ですが、実際は何が同じ文字列になるのかわからないこととします。
0356nobodyさん
03/05/24 18:17ID:???Location:
で飛ばさない方法というのは如何でしょうか?
>>355
可能です。
と、答えると逆ギレされるのだろうか?
この世の中ってば、ほんと怖いです。
ま、「1文字一致」っていうのもあるから許されますよね?ね?ね?
0357nobodyさん
03/05/24 18:18ID:LfXTm2oZ0358354
03/05/24 18:20ID:CEfAWsDpロケーションで飛ばさない、、といいますと??
ほかに方法がありますか?あればぜひご教授ください。
0360354
03/05/24 18:32ID:CEfAWsDpファイルの中身をcgiに記述する、、、ということでしょうか?
ぜんぜんわかりません、ごめんなさい。
もう少しわかりやすくお願いできますか?
0361nobodyさん
03/05/24 18:36ID:???どちらにせよ、「DLを試みた回数」はわかっても、「DLを完了した回数」はわからないよ?
途中で回線切断されたら終わりだし。
0362354
03/05/24 18:41ID:CEfAWsDpそうですか。。。
途中で切断でもいいので、「保存」を押して転送が開始された時点でのカウントでもいいのですが・・・
0364354
03/05/24 18:44ID:CEfAWsDpわかりました。探してみます
0365354
03/05/24 18:56ID:vyZFmtfU、、これであきらめます。
0366nobodyさん
03/05/24 18:56ID:???CGI使わずに、鯖のアクセスログとか見た方が鯖に優しいぞ。
0367nobodyさん
03/05/24 19:16ID:4X2MnE2OITスクールを開催しています。
スクール形式は1dayパックで3時間だけです。
授業料金は安く、即、実践へ活用できます!
http://homepage3.nifty.com/it3s/index.htm
0369355
03/05/24 20:11ID:???> 可能です。
そうですか。。。
漏れにはその方法がわからないけど、こんな風なのはどうか評価してください。
連続する5文字が両方にあったら真とするということに勝手にします。
で、$value1、$value2とも最初の5文字を@value1、@value2に入れる。
次に2文字目から6文字目までの5文字を配列に入れる。
以下繰り返し。
最後に@value1、@value2の比較。
駄目でしょうか?
2バイト文字があったら、、、ダメミタイダナァァァァァアアアアアアアアアアああああああ!!!!!
0370nobodyさん
03/05/24 21:11ID:???頼むから本一冊買って勉強してくれ。
http://www.google.co.jp/search?num=100&hl=ja&q=Perl+%E3%83%91%E3%82%BF%E3%83%BC%E3%83%B3%E3%83%9E%E3%83%83%E3%83%81&lr=lang_ja
0371nobodyさん
03/05/24 22:21ID:???ちょっと俺が間違ってた。
CGIで吐くんじゃなくて別のポートを見張るサーバを別に立てて、そこへ向けてLocationで飛ばす。
で、送出できたバイト数を数えればダウンロードできたかどうか分かる。
簡易HTTPサーバ作るってこと。
0372356
03/05/24 22:27ID:???> で、$value1、$value2とも最初の5文字を@value1、@value2に入れる。
あのぉ、、、(汗)
> 駄目でしょうか?
さすがに「しゃーねーなぁ、、、それでいこか。」とは口が裂けても云えませんm(_ _)m
> 2バイト文字があったら、、、ダメミタイダナァァァァァアアアアアアアアアアああああああ!!!!!
さんざん既出だとは思うが、文字コードを云々・・・
「検索アルゴリズム」
いっぺんこれでググってみると新しい道が見つかるかもよ。道は険しいけれども。
(「木」「ハフマン」「辞書」とか出てくるかもしれんが@「圧縮」も似たようなもん)
0373nobodyさん
03/05/24 22:46ID:???if ($value1.$value2 =~ m/(.+).*\1/i) {
my $word = $1;
if ($value1 =~ /$word/i && $value2 =~ /$word/i) {
print $word,"\n";
}
}
こういうのはいかが?
0374nobodyさん
03/05/24 22:47ID:???0376nobodyさん
03/05/24 22:49ID:???あなたが、何を文字列として定義するか(重要)で
難しさは極端に変わりますが、簡単な \w+ を例に
するとこんな感じでしょうか。
my $value1 = 'http://www.yahoo.co.jp';
my $value2 = 'Copyright (C) 2003 Yahoo Japan Corporation. All Rights Reserved. ';
if ( reword($value1, $value2) ) {
print '重複した単語がある';
} else {
print '重複した単語はない';
}
sub reword {
my $str = shift;
my $substr = shift;
my (%word); # 単語用ハッシュ
$word{"\L$1"}++ while $str =~ /(\w+)/g; # 単語をキーに登録
$word{"\L$1"} && return 1 while $substr =~ /(\w+)/g; # 登録済みなら真を返す
return 0; # 無かった
}
0377343
03/05/25 00:49ID:???お礼が遅くなり、申し訳ございません。
無事にサンプルスクリプトを動かす事が出来、それを踏まえて自分のスクリプトでやりたい事が実現できました。ありがとうございます。
しかし、上記のサンプルコードでプラス変数を追加し、文字列変換の def 部分をその変数で置き換えた場合にエラーが出てしまいました。
変数を表す場合は、@{$_[3]}ではダメだとまでは判別できるのですが、実際の表記の仕方が見当もつかない状況です(連想配列の場合もそうなんですが)
そこで、答えそのものではなくても、strict使うのであればここを読め、の様なサイトはないでしょうか?
>>4のサイトを全て回りましたが、普通に*で渡すようにとの解説ばかりでした。
0378349
03/05/25 01:32ID:???use strict 以前の話なのですよ。343さんがハマってる部分は。
むしろ use strict は全然関係無し。
まず * が何を表していて、何故 \ が出てきたか、@{ } は何を
しているのか、どうしてこのコードで引数に渡した配列そのもの
の値を置換する事ができるのか。そういう点を全部読み解き、
理解しましたか?
あと、エラーが出た場合はどんなエラーが出たのか言って
くれないと、何が悪いのかサッパリ見当付かないですよ。
0380343
03/05/25 02:15ID:???ご指摘ありがとうございました。
ご指摘いただいている箇所の理解が全然足りないようです。
先ほどから検索をかけて、
http://www.kt.rim.or.jp/~kbk/perl5.005/perlref.html
あたりが見つかりましたので、そこを熟読して、あと手元に青ラクダ本がありますので、
シンボリックリファレンス項目あたりも熟読してから再度チャレンジしてみようと思います。
それと質問をする側として必要な情報の提示を怠り、申し訳ありませんでした。
自分の理解を深めてから再度頑張ってみます。
>>379
お勧めサイトありがとうございます。
色々と載っていて、とても役に立ちそうです。
0381nobodyさん
03/05/25 13:54ID:sMN/Ic1bそこで長い間つかえるように日記のログを年、月と階層的にディレクトリを
作り、ユニークなログを実現したいです。
そこで、
opendir(LOG,"./Log") || die mkdir("./Log", 0755);
opendir(YEAR,"./Log/$year") || die mkdir("./Log/$year/",0755);
opendir(MONTH,"./Log/$year/$month") || die mkdir("./Log/$year/$month",0755);
のようなスクリプトを実行してみました。
./Log/$year/で$monthディレクトリ1つが無い時は正常に動作しましたが、
ディレクトリを2つ以上作成したい時でも1つしか作る事ができませんでした。
これを解決するための原因をご存知の方がいらっしゃいましたらよろしくお願いします。
環境:OS Win2000
Perl 5.6.1
0382nobodyさん
03/05/25 15:17ID:???困ったことに同一環境で正常に動作しました。
テスト方法は、上記のスクリプトの先頭に、
print "Content-type: text/html\n\n";
$year = "2003"; $month="5"; print "$year $month\n";
を追加して、$monthを変更しつつ数回実行。
0383381
03/05/25 15:37ID:sMN/Ic1b試していただき、ありがとうございます。
上記の時間はlocaltime()で取得したものです。
書き方がとても下手ですみません。
例えば、今年の2003年1月のログが/Log/2003/1に格納されていた場合、
年が明け、来年の2004年1月になった時/Log/2004/1とLogディレクトリ下に2004ディレクトリ、
そのまた下(Logから見て2階層下)に1ディレクトリを作りたいです。
しかし、上記のスクリプトでLog以下のディレクトリを作成せずに実行すると、一回目は「Logディレクトリ」、
二回目は「5ディレクトリ」と、一回の実行で一つのディレクトリしか作れません。
>>382さんのコードですと、同階層のディレクトリを複数個作っているんですよね。
もしまだお付き合い頂けるのでしたらまた宜しくお願いします。
#現在はとりあえず200Xディレクトリと1〜12ディレクトリを予め複数個用意して他の部分を作っています。
コンソールからmkdir /Log/$year/$month で$yearと$monthのディレクトリが作成できるのに
なぜスクリプトからだとできないのだろう・・・
0384nobodyさん
03/05/25 16:33ID:???die使わなければいいだけでしょ。
エラー処理じゃなく分岐したいだけでしょ?
ファイルテスト演算子の-eでディレクトリがあるかどうか判別したら?
0385nobodyさん
03/05/25 16:42ID:???以下のURLにある、商品名とメールアドレスを入力してボタンを押すと、検索結果を入力した
メアド宛てに送信するというシステムがあるのですが。
該当ページURL
ttp://www.hakuraiya.way.cc/quote.html(海外の薬を個人輸入代行する業者のページです)
で、ソースを見ると
http://www.hakuraiya.way.cc/cgi-local/order/quotemail.cgi
こういうCGIに入力データが送られ、検索処理後にメール送信しているようなのですが、これは
どういう風に動いているんでしょう?
入力されたデータを処理し、予め用意した商品リストと照合・検索して、結果をメール送信する
わけなので、最低でも処理用CGIスクリプトと商品データファイルが必要なところまでは理解
出来るのですが、仕組みがイマイチわかりません。
スクリプト名等で検索しましたが全くHITしないし、こういうシステムは商用&有償なのは想像が
つきます。私自身はこれで商売をしようという気持ちはなく、自分のCGIの勉強の教材にしたいと
考えているので、以上のシステムに心当たりがある方、または「こういう風にスクリプトを組んで
いるんじゃないか?」という風に教えてくださる方、どうかご助力ください。
よろしくお願いします。
0386nobodyさん
03/05/25 16:48ID:???>入力されたデータを処理し、予め用意した商品リストと照合・検索して、結果をメール送信する
仕組みは自分で答えを言っちゃってるじゃん
検索スクリプトの結果をブラウザに返す替りにメール本文にするって
そんなに難しく考えることじゃないと思うけど
こんなCGI探してますスレッド ver.9
http://pc2.2ch.net/test/read.cgi/php/1051456859/l50
ここのリンク集を探せばあるかも、あるいはないかも
0388nobodyさん
03/05/25 17:29ID:???アルゴリズムに関する質問はスレ違いじゃないみたいよ。
最終的にはコーディングを目標にしてるみたいだからいいじゃん。
>>385
リンク元は見てないけど、結果を表示しつつsendmailでメールを送ればよろしい。
難しいことじゃないよ。
0389nobodyさん
03/05/25 17:30ID:LMu0ezCc}
こういうif文を書くと、1番目と2番目の(.+)はそれぞれ$1、$2と
なるのでしょうか。
それとも両方とも$1となるのでしょうか。
すみませんが教えていただければ幸いです。
0390nobodyさん
03/05/25 17:37ID:???なぜ試さない?
0392nobodyさん
03/05/25 18:04ID:???>>384の言うとおり、dieを使うとその時点でスクリプトが終っちゃう。
手元のリファレンスによると、孫ディレクトリは子ディレクトリが無いと作れないみたい。
どうしてもやりたい場合は、File::Pathモジュール使うとよい、とあった。
0393nobodyさん
03/05/25 18:35ID:???そこに試す環境がなかったので、質問させていただきました。
友達に聞かれて答えられなかったので。
会社にに戻って試してみましたので、すみませんでした。
おっしゃるとおりです。
ちなみに。>>391は偽者ですので。
この書き込みも、会社から書き込めないことから、友達の家
より代理書き込みしてもらってるので、IDでわかるかと思います。
0394385
03/05/25 18:48ID:???レスどうもありがとうございます。
>>386
>検索スクリプトの結果をブラウザに返す替りにメール本文にする
ああ、なるほど!そうすればいいのか。仰るとおり、難しく考えすぎていました。
>>388
こちらも、ヒントありがとうございます。上に書いたとおり、難しく考えすぎていたので
胸のつかえが取れたような気分です。助かりました。
お二方のレスを参考に、検索+sendmailのスクリプトを探して、組み込み改造など
頑張ってみたいと思います。本当に、どうもありがとうございましたm(_ _)m
0396nobodyさん
03/05/25 23:52ID:???そして使わなくなったものを undef していないから
メモリを大量に使ってしまうのですか?
0398nobodyさん
03/05/26 00:24ID:6A9UvBAu<INPUT TYPE=FILE NAME=file>
のファイル本体部分を取り出すのに
$buf =~ /(\r\n)$1(.+)\1-{10,}/;
$date = $2;
と書いてバッチシいくでしょうか?
$buf =~ /Content-.+(\r\n)$1(.+)\1-{10,}/;
上はどうでしょう?
ご意見おながいします。
0399398
03/05/26 00:27ID:???誤 \1
正 $1
です。
0401398
03/05/26 00:39ID:???ググってきます。
0403398
03/05/26 01:27ID:???http://pc2.2ch.net/test/read.cgi/php/1024795138/383
で質問したんですが誰もいないみたいなので
こちらで誰か教えてください。
おながいします。
0404398
03/05/26 01:43ID:???use CGI;
$query = new CGI;
と書いたときモジュールが使えなかったらエラーになりますか?
それとも
if($query){}
と、できますか? どうなんでしょう?
0406nobodyさん
03/05/26 03:15ID:???俺も相当アフォだな、、、逝ってこよう。
0408380
03/05/26 04:00ID:tTZ2AIlQchompを実行させても\r\nを改行と見なしてくれないのですが、
読み取られファイルをEUCにするのとchompの代わりに↓
$data =~ s/\r\n//g;
$data =~ s/\r//g;
$data =~ s/\n//g;
を使う。という方法以外で一般的な方法というのは無いのでしょうか?
0409380じゃないです
03/05/26 04:07ID:???名前入力してしまいましたが380は間違えです。
0410_
03/05/26 04:16ID:???0412nobodyさん
03/05/26 05:19ID:???$data =~ tr/\x0d\x0a//d;
が高速。
0413nobodyさん
03/05/26 06:37ID:qholo4T7ことを考えてるのですがこれって実現可能ですか。
リストで表示させる項目を一つの変数の中にまとめて
"a","b","c"と書いても実行するとリストは"a","b","c"と
繋がって表示されてしまい1項目しかでなかったものでして。
ある人は10個項目でててある人は5項目でてるような
ことがしたいのです。
0415nobodyさん
03/05/26 10:06ID:???言ってる意味がよーわからんので推測でだが、出来る。
ユーザごとに指定した数を指定しておいて、配列をその数だけ
回すなりなんなりでいいんじゃん?
0417nobodyさん
03/05/26 10:20ID:???>>414
添付ファイルはどこに誰が保存しているのか?
そのファイル名はメール内でのファイル名だと思うのだが
>>419
$?
0419nobodyさん
03/05/26 10:36ID:???未だにPerl4の鯖だってあるんだよ。
0420nobodyさん
03/05/26 11:01ID:X5HT6fof$orgid = $line{'orgid'};
$countryid = $line{'orgname_ja'};
$orgname = $line{'orgname'};
っていうのを、後ろの3行をベタにこういう風↑に書かないで、
foreach $value (@orgmaster) {
★ここが不明★ = $line{$value};
}
というようにまわしたいのですが、
★ここが不明★の部分がわかりません。どうすればいいのでしょうか?
0421bloom
03/05/26 11:08ID:gUjk1KcM0424nobodyさん
03/05/26 12:52ID:???$ORG{'person'}[2]、$ORG{'adana'}[2]、$ORG{'adanaid'}[2]
$ORG{'person'}[3]、$ORG{'adana'}[3]、$ORG{'adanaid'}[3]
$ORG{'person'}[4]、$ORG{'adana'}[4]、$ORG{'adanaid'}[4]
$ORG{'person'}[5]、$ORG{'adana'}[5]、$ORG{'adanaid'}[5]
という変数があるのですが、これを、
$ORG{'adanaid'}[n]の値でソートして、例えば、
$ORG{'person'}[2]、$ORG{'adana'}[2]、$ORG{'adanaid'}[2]
$ORG{'person'}[5]、$ORG{'adana'}[5]、$ORG{'adanaid'}[5]
$ORG{'person'}[4]、$ORG{'adana'}[4]、$ORG{'adanaid'}[4]
$ORG{'person'}[3]、$ORG{'adana'}[3]、$ORG{'adanaid'}[3]
$ORG{'person'}[1]、$ORG{'adana'}[1]、$ORG{'adanaid'}[1]
みたいに表示さすにはどうすればいいのでしょうか?
0426nobodyさん
03/05/26 14:22ID:???0427426
03/05/26 14:23ID:???手元のリファレンスには何にもかいてなかったもんで
0428nobodyさん
03/05/26 15:09ID:ave5j164http://www.2ch.net/dir/file.txt
という文字列を、
/dir/file.txt
のようにするにはどちらが効率的なんでしょうか?
# 正規表現のみの場合
$url =~ s/http:\/\/.*?\//\//i;
# 関数も使う場合
$url =~ s/http:\/\///i;
@temp = split(/\//, $url);
shift(@temp)
$url = "/" . join("/", @temp);
0430nobodyさん
03/05/26 15:49ID:???http://flex.ee.uec.ac.jp/texi/perl/perl_54.html
■ このスレッドは過去ログ倉庫に格納されています