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

Perlコーディング初心者質問スレ Part 60

■ このスレッドは過去ログ倉庫に格納されています
0001nobodyさん2009/09/03(木) 23:51:12ID:???
Perlのコーディングで困ってる人のスレです。

【投稿する際の注意】
質問するときは内容をよく吟味してから投稿してください。
「コマンドの意味がわかんない」とかはマニュアル見ましょう。
回答者さんは何でも屋じゃありません。

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

最低でも1と3が無いと誰も答えられないよ。
良い回答は良い質問から。一緒に勉強しましょう。

お勧めサイトは >2 以降

前スレ http://pc11.2ch.net/test/read.cgi/php/1234752149/
0002nobodyさん2009/09/03(木) 23:52:22ID:???
[プログラミング自体の経験が無い奴はまずココを読め]
Perlプログラミング講座: ttp://www.site-cooler.com/kwl/perl/

[本]
リャマ: ttp://www.oreilly.co.jp/books/4873111269/
駱駝: ttp://www.oreilly.co.jp/books/4873110963/
Effective Perl: ttp://ascii.asciimw.jp/books/books/detail/4-7561-3057-7.shtml
クックブック: ttp://www.oreilly.co.jp/books/4873112028/
Perl ベストプラクティス: ttp://www.oreilly.co.jp/books/4873113008/
Perl Hacks: ttp://www.oreilly.co.jp/books/9784873113142/

[オンラインマニュアル]
最新のドキュメント: ttp://perldoc.perl.org/
perl5.8.xのドキュメント(一部): ttp://www.kt.rim.or.jp/~kbk/perl-5.8/
perldoc きまぐれ訳: ttp://fleur.hio.jp/perldoc/
perldoc.jp: ttp://www.perldoc.jp/

[モジュール]
CPAN: ttp://search.cpan.org/
河馬屋二千年堂: ttp://homepage3.nifty.com/hippo2000/

[テクニック]
Perlメモ: ttp://www.din.or.jp/~ohzaki/perl.htm
Perlのページ: ttp://homepage1.nifty.com/nomenclator/perl/
Perlの小技: ttp://homepage3.nifty.com/hippo2000/perltips/index.htm

[Perl5.8Unicodeメモ]
ttp://www.namazu.org/~tsuchiya/perl/perl-5.8.html
ttp://www.lr.pi.titech.ac.jp/~abekawa/perl/perl_unicode.html
0003nobodyさん2009/09/04(金) 05:49:19ID:???
いちおつー。
0004nobodyさん2009/09/04(金) 13:17:39ID:???
4様
0005nobodyさん2009/09/04(金) 15:10:46ID:???
私が立てた過疎スレもどうぞよろしく

【Perl,CGI】参考書籍 第四版
http://pc11.2ch.net/test/read.cgi/php/1250989562/
0006nobodyさん2009/09/10(木) 01:26:11ID:tlO5UesG
最初の質問させていただきます。
演劇サークルで次に演じる脚本があるのですが、その脚本が、セリフが役名:セリフか役名:セリフで区切ってあり、
ト書きとわかりづらいということでhtmlのtableを使って表にしようとしたのですが、文法チェックにかけると
syntax error at C:\cgi\henkan\sreplace.cgi line 10, near ") {"
syntax error at C:\cgi\henkan\sreplace.cgi line 30, near "}"
C:\cgi\henkan\sreplace.cgi had compilation errors.
と出て、whileの実行式部分のカッコにエラーが出るし、それを削除してもsplitで値を代入する先の()が不要だ、と出ます。
次に貼るソースコードのどこに問題があるか教えていただければ幸いです。
わかりにくいと思いますので
要するに、
$fileというファイルの文を、$splitをデミリタにして$nameと$naiyouに分けて代入し、
$naiyouの値が空なら(ト書きのとき)$nameを$naiyouに代入、その内容を二つのファイルに分けて保存し、
最後にそれをまとめて二つの<TD>に$nameと$naiyouがきれいに分かれているhtmlファイルを作りたいのです。
下のコードのどこが問題なのか教えてください。
0007nobodyさん2009/09/10(木) 01:28:19ID:tlO5UesG
#!/usr/local/bin/perl

use CGI;
$q = new CGI;

$file = $q->param('file');
$split = $q->param('split');

open(FILE, "<$file")
while($ln = <FILE>) {
$ln =~ s/\n/<br>/g;
$ln =~ s/$split/$split<b>/g;

($name, $naiyou) = split(/$split/, $ln);

if($naiyou == "")
{$name = $naiyou ;
}
unless($name == ""){
$naiyou = "$naiyou</b>";
}

続きは次に書きます。
0008nobodyさん2009/09/10(木) 01:29:56ID:tlO5UesG
open(OUT,"> name.log");
print OUT "$name";
close(OUT);
open(PUT,"> naiyou.log");
print PUT "$naiyou";
close(PUT);
}

close(FILE);

open(IN,"< name.log");
@name = <IN>;
close(IN);

open(RE,"< naiyou.log");
@naiyou = <RE>;
close(RE);


print "Content-type: text/html; charset=Shift_JIS\n\n";
print "<html>\n<head><title>移動</title></head>";
print "<body><a href='kyakuhon.html'>脚本へ移動<\/a></body>\n</html>";

open(SYU,"> kyakuhon.html");
print SYU "<html>\n<head>\n";
print SYU "<META HTTP-EQUIV=\"Content-type\" CONTENT=\"text/html; charset=x-sjis\">\n";
print SYU "<title>Scenario</title>\n";
print SYU "</head>\n";
もう一度次です。長くなって申し訳ないです
0009nobodyさん2009/09/10(木) 01:32:15ID:tlO5UesG
print SYU "<body>\n" ;
print SYU "<table border>";
print SYU "<tr>";
print SYU "<td width=25%><b>役・備考</b></td>";
print SYU "<td width=75%><b>セリフ・ト書き</b></td>";
print SYU "</tr>";
print SYU "<tr>";
print SYU "<td width=25%><b>@name</b></td>";
print SYU "<td width=75%>@naiyou</td>";
print SYU "</tr>";
print SYU "</table>";
print SYU "</html>";
close(SYU);
長文申し訳ありませんでした
0010nobodyさん2009/09/10(木) 02:41:05ID:???
最初の open のセミコロン

今回はエラーとして出んかもしらんが、今後のためにも面倒でも use strict してくれ

それから文字列を比較するときは == じゃなくて eq な
特に空文字かどうかの比較は

$hoge eq '';
$hoge ne '';
みたいに書く癖をつけたほうがいい
0011nobodyさん2009/09/10(木) 03:07:22ID:???
open(FILE, "<$file")に ; が無い
0012nobodyさん2009/09/10(木) 07:34:56ID:xEU2hsmO
>>10-11さん
ありがとうございます。今はちょっとPCを開く時間がないので無理ですが、学校で修正したいと思います。
こんな初歩のミスだとは…
もっと頑張らなきゃいけませんね
本当にありがとうございました。
0013122009/09/11(金) 00:27:02ID:j5Qgkl9c
修正したんですが、まだ駄目でした。コードは変わってないです。
whileあたりに何か問題があるみたいなんですが、わからないです。
0014nobodyさん2009/09/11(金) 00:39:31ID:???
駄目でしたじゃなくて、○○なので駄目でしたとした方がいい。
今後全てにおいて。
0015122009/09/11(金) 00:48:46ID:j5Qgkl9c
すいません。
お二方が教えてくださったとおり変えてみたところ500エラーは出なくなったんですが、
出力したHTMLに中身が残らず、name.logもnaiyou.logも空のままでした。
while($ln = <FILE>){
#$ln =~ s/\n/<br>/g;
#$ln =~ s/$split/$split<b>/g;
#$ln =~ s/(//g;

#($name, $naiyou) = split(/$split/, $ln);

#if($naiyou eq '')
#{$name = $naiyou ;
#}
#unless($name eq ''){
#$naiyou = "$naiyou</b>";
#}


open(OUT,"> name.log");
print OUT "$ln";
close(OUT);
open(PUT,"> naiyou.log");
print PUT "$ln";
close(PUT);

close(FILE);
}
にまでしても上手くいかなかったのでwhile部分の問題だと思ったのですが、何がおかしいのでしょうか?
0016122009/09/11(金) 00:50:24ID:j5Qgkl9c
↑上手くいかなかったではなくどちらの.logも空のままだった
です。
0017nobodyさん2009/09/11(金) 10:04:31ID:???
while 内部で close(FILE); してるよ。
0018nobodyさん2009/09/11(金) 10:55:18ID:???
>>15
whileループが必ず1回で終わりますね。close(FILE)しているから。
open(OUT,"> name.log");
と
open(PUT,"> naiyou.log");
はopenに失敗しても、そのまま無視されて処理が進むので、エラートラップするのが鉄則です。
すなわち、
open(OUT,"> name.log") or die $!;
open(PUT,"> naiyou.log") or die $!;
など。$!は最後のエラーメッセージが格納される特殊変数です。
よくあるのはパス違い、書き込みパーミッションが立っていないなど。

そもそも、
open(FILE, "<$file");
が失敗している可能性もあり。それだとwhileループは実行されていないことになる。
0019122009/09/12(土) 02:32:58ID:83ZTZfsA
openは成功してました。一行だけ読み込んだら問題なく表示されたので。
そういえば、splitってデミリタがその対象になる文字列内になかったらどうなるんですか?
0020122009/09/12(土) 02:36:32ID:83ZTZfsA
あ、わかりました。
すいません。
パスも、書き込みもあってて、openできてて、コードチェックも問題なく通るのに出来ないんです。
while($ln = <FILE>)
という記述が問題になる可能性はありますか?
0021122009/09/12(土) 03:10:26ID:83ZTZfsA
度々すいません。
やっと解決しました。
全部処理は上手くいっていたのですが、openの後ろが>だったために、書くたびに内容を上書きしてしまい、
最後の行の\nだけが書き込まれるという形になっていたみたいです。
助言してくださった皆さん、本当にありがとうございました。
いつか自分ももっと精進して皆様のように初心者に優しく教えられるようになりたいと思います。
0022nobodyさん2009/09/12(土) 03:26:39ID:???
>>21
とりあえず100年ROMしてろ
0023nobodyさん2009/09/12(土) 09:20:58ID:???
> とりあえず100年ROMしてろ

ROM 期間中に死を迎えることになりそうなので、軽減してもらえませんか
0024nobodyさん2009/09/14(月) 10:33:35ID:???
>>23
誰も来なくて暇だから明日まででいいよ
0025nobodyさん2009/09/14(月) 11:59:40ID:t5y5v7j/
くだ質の方にしようかと思いましたが、こちらで投稿致します。

perl -pe "s/foo/bar/g" *.txt

これをスクリプトで書くにはどうしたらよいのでしょうか?
以下のように書くと、0バイトファイルが出来上がります・・・

opendir DH,$dir or die;
my @files = readdir DH;
closedir DH;

foreach my $file(@files){
next if $file =~ /^\.{1,2}$/;
open(FH,"+>$file");
while(my $ln = <FH>){
$ln =~ s/foo/bar/;
}
close FH;
}

よろしくお願いします。
0026nobodyさん2009/09/14(月) 12:28:27ID:???
>>25
http://perldoc.jp/docs/perl/5.10.0/perlrun.pod#item__b__p__b___p

while (<>) { s/foo/bar/g } continue { print or die "-p destination: $!\n" }

本当にやりたい事には -i オプションが抜けてる気がするけどね
0027nobodyさん2009/09/14(月) 13:03:07ID:???
>>25
opendir my $dir_fh, "." or die $!;
my @files = grep { (not /^\./) and -f } readdir $dir_fh;
closedir $dir_fh;

for my $file (@files) {
open my $fh, "+<", $file or die $!;
my @contents = map { s/foo/bar/; $_ } <$fh>;
seek $fh, 0, 0;
print {$fh} @contents;
}
やってみたいことと違うかもしれないけど
0028nobodyさん2009/09/14(月) 13:58:11ID:???
>>27 barの部分に入る文字列がfooの部分に入る文字列より短いと変なことになったので訂正
opendir my $dir_fh, "." or die $!;
my @files = grep { (not /^\./) and -f } readdir $dir_fh;
closedir $dir_fh;

for my $file (@files) {
open my $in, $file or die $!;
my @contents = <$in>;
close $in;
open my $out, ">", $file or die $!;
print {$out} map { s/foo/bar/; $_ } @contents;
close $out;
}
0029nobodyさん2009/09/14(月) 14:27:32ID:t5y5v7j/
>>26-28
ありがとうございます。
バックアップいらないから、と思いきや、上書自体-iが必要だったのですね・・・・確認不足でした。
>>26を参考に、上書ができない状態で90分ほど彷徨っていますが、これから>>27-28を試してみます。
お礼ついでに経過報告まで・・・
0030nobodyさん2009/09/14(月) 14:45:14ID:t5y5v7j/
>>28
出来ました!
しっかり噛み砕いて、自分の物に致します。
ありがとうございました。
0031nobodyさん2009/09/14(月) 18:22:59ID:???
一応書いとく。
ワンライナーが本来どう解釈されるかを見るには、B::Deparseを使う。

% perl -MO=Deparse -i.bak -pe "s/foo/bar/g" *.txt
BEGIN { $^I = ".bak"; }
LINE: while (defined($_ = <ARGV>)) {
 s/foo/bar/g;
}
continue {
 print $_;
}
-e syntax OK

そのまま必要部分をコピペしたらスクリプトの出来上り。

0032nobodyさん2009/09/14(月) 20:02:28ID:???
html template で分離されたテンプレートのほうに、
php埋め込んで稼働出来るようにならないでつか?

html templateで完成された奴をphpでコーティングしたいんだけど・・
■ このスレッドは過去ログ倉庫に格納されています