人気マンガがだれでも無料♪電子コミック読み放題!!

Perlの変数に文字数制限(容量制限)はあるか

Perlで書いた自作の掲示板なのですが、ずっと普通に動いていたのですが
急にデータが欠けてしまいました。書き込みデータはテキスト形式で、
↓の様な形で保存しています。

<div>1つの書き込みの中身</div>\n
<div>1つの書き込みの中身</div>\n
<div>1つの書き込みの中身</div>\n
<div>1つの書き込みの中身</div>\n
<div>1つの書き込みの中身</div>\n

1つの書き込みは1行に収まっていて、書き込み時に \n を付けて保存して、
読み込み時は配列に読み込んで、べろっと出すだけの処理です。
掲示板書き込みなので unshift で上が新しい書き込みにしてあります。
通常のタグ禁止処理や、改行コード処理はしてあります。Perl5.6.1です。

数日前、容量が減っていることに気付き、調べてみると、

<div>1つの書き込みの中身</div>\n
<div>1つの書き込みの中身</div>\n
<div>1つの書き

のような形でデータが欠けていました。欠けていると言っても9割方消えていました。
残っていたのは新しい側の書き込みです。
いつ消えたのか、何をした時に消えたのかが不明のため、原因を探っている段階です。

もちろん、一番怪しいのはプログラムのミスなのですが、それも調べつつ、
ちょっと前から気になっていた点として、データ容量が1.5MBぐらいまで
ふくらんでいて重くなっていたんです。
data.dat のような1ファイルにテキストばかり1.5MB、そして内部の処理でも
普通にその容量を一つの変数に入れたりしています。
データが唐突にぶつっと切れていることと、容量が多くて気になっていたこと、
この辺りでちょっと怪しいのですが、変数の容量制限、ファイルの容量制限が
調べても出てきません。知っている方いましたら教えてください。

他にも、そういうバグの時こういうミスがあったよ、など、ありましたら
アドバイスをお願いします。
自分が作った物のデバッグで恐縮なのですが、よろしくお願いします。

このQ&Aに関連する最新のQ&A

A 回答 (8件)

No.3&6です。



> flock してません・・・・・・。
> つまり、読み込み時に競合があって書き込まれたため、開いたままのデータが
> 変なところで書き込み処理に割り込まれて、おかしくなったということでしょうか。
> でしょうか、というか、その可能性があった、というところですかね?

ちょっと説明が足りなかったので補足します。

読み込み時にflock()しなかった場合ですが、書き込みが純粋に追記だけの場合は(記事表示で途中で切れることはあるかもしれませんが)データファイルの破損までは至らないかなと思います。もちろん、読み込み内容が壊れるには違いないですので、読み込みルーチンにもflock()は追加すべきです。

データファイルが壊れるケースですが、既存記事の修正機能が実装されている場合などで、読み込みルーチンで取得した@BbsDataの値を使った書き込みルーチンが別にあった場合には、たとえその書き込みでファイルロックがされていたとしてもデータファイルが壊れることになります。

もっともその場合、データ変更に関する一連のロジック自体を見直す必要があるかもしれません。
既存記事の変更を行う場合には、「一度のファイルオープン+ファイルロックの間に、読み書きを全て済ませる」という処理に置き換えないと、ほぼ同時に複数の書き込みが発生した場合に一部のデータが失われるという別の不具合が発生する恐れがあります。ご参考まで。

この回答への補足

読み込み時、flock処理を追加してみます。

# 書き込みデータの読み込み
open( BBS, "< ../data/bbs.dat" );
flock( BBS, 1 );# ロック
@BbsData = <BBS>;
$BbsCount = @BbsData;
close ( BBS );


修正機能は付いていません。
でもそのうち付けようと思っていたので、付ける時にロック系、気を付けたいと思います。

とりあえず再開に向けて、処理するデータを小さくし、読み込み時に flock処理を追加してみます。
あと今回のことを一応、サーバー会社に聞いて返事を待つと。


それからもうちょっと頻繁にバックアップを取ります。。。
Googleにキャッシュが残っていたので少しサルベージしましたが、抜けが出てしまいました。
Google以外でそういうキャッシュが自動的に残っている可能性のあるサイトってありませんかね?

xxx.cgi に最初の20件、
xxx.cgi?page=1 だと21件~40件、
xxx.cgi?page=2 だと41件~60件、
xxx.cgi?page=3 だと61件~80件

という感じで表示させていたのですが、別ページ扱いなのでキャッシュが残ってたりするんですよね。

補足日時:2010/07/01 18:06
    • good
    • 0
この回答へのお礼

別の質問になってしまったので立て直します。
回答してくれた皆様、ありがとうございました。

お礼日時:2010/07/02 10:20

CGIを動かしているのがレンタルサーバ(などの第三者が設定した環境)であって、


壊れたファイルが0や8192バイトなどの切りの良い(?)サイズで切れているなら、
ファイル書き込み中にシグナルで殺されている可能性も考えられそうです。

時間のかかるCGIを制限しているレンタルサーバだと、
比較的短い時間でタイムアウトして、CGIにSIGTERMやSIGILLLが飛んできて、
プロセスが殺されることがあります。
ファイルサイズが増えれば、書き込みに要する時間も長くなるので。

もしそうだとすると、解決策は・・・
SIGTERMを無視してみても、最後にはSIGKILLが飛んでくると思うので、
処理を早く終わらせるしかなさそうです。

例えば、一定行数ごとにファイルをわけて、表示時はページ制御するとか。
表示&保存する件数を、全部はあきらめて最新何件などに減らすとか。

他には、limitでメモリ制限されてる、なんて可能性もありますが、
それだとファイル書き出しより前の時点で落ちるでしょうから、
今回の原因としては考えにくいですね。

この回答への補足

回答ありがとうございます。

サーバーはレンタルサーバーですが、壊れたファイルは 114,898バイトでした。
キリのいい数値ではなさそうです(たぶん)。
一応サーバーに、そういうことをすることもあるか聞いてみます。

動いていた時も書き込みに1秒ぐらいかかっていたので、これまでの累積を
いっぺんに開いている状態はやめて、もうちょっとすっきりさせたいと思います。

補足日時:2010/07/01 16:40
    • good
    • 0

No.3で回答した者です。



追加書き込みのロジック自体は問題ないように見えます。
# 強いて指摘するなら、追記のみの場合はファイルサイズが小さくなることはありませんので、truncate()によるファイル全消去が不要なくらいでしょうか。
# seek(WRITE, 0, 0)だけで十分です。
# 余談ですが、ファイルサイズが減る可能性がある場合においても
# ファイルを全消去してから書き込むよりは、先頭へシーク+全データ書き込み後に
# truncate(WRITE, tell(WRITE));
# とした方が、ディスク処理のオーバーヘッドが少ないです。

で、書き込みが問題ないとなると、やはり読み込み処理に問題があるのではないでしょうか。
公開して頂いたサブルーチンを見る限り、おそらく「読み込み用」サブルーチンが別にあるのではないかと推測します。
# でないと、追記しない限り読めないことになりますから・・

Perlのflock()による排他処理は(OSにもよりますが)flock()を利用したファイルオープンに対してしか機能しません。従って、ファイル読み込み時にも
open(HANDLE, ...);
flock(HANDLE, 1); # リードオンリーモードでロック
といった処理が必要になります。
これを忘れた場合、質問者さんのような症状が発生する可能性があります。

この回答への補足

おっしゃる通り、全書き換えの時のロジックを、追記の時も使い回して、
まあ、余計な動きをしているけど動くからいいか、とそのままにしていました。
余計な部分は省くように参考にさせていただきます。


読み込み部分ですが、そのまま貼り付けます。
1ページに20件表示とかする用に行数($BbsCount)も取得しています。

# 書き込みデータの読み込み
open( BBS, "< ../data/bbs.dat" );
@BbsData = <BBS>;
$BbsCount = @BbsData;
close ( BBS );

flock してません・・・・・・。
つまり、読み込み時に競合があって書き込まれたため、開いたままのデータが
変なところで書き込み処理に割り込まれて、おかしくなったということでしょうか。
でしょうか、というか、その可能性があった、というところですかね?

補足日時:2010/06/30 02:31
    • good
    • 0

現在の Perl の実装では, 文字列を「長さ+内容」という形で記憶します (C とは異なり「終端に特定の文字がある」という形ではない). この「長さ」を確か int で記憶しているはずなので, 「1つのスカラーに記憶できる文字列の長さ」は限界があります. 現状ではシステムによらず 32ビット符号付きで上限は 2GiB-1 だったかな? 配列やハッシュの要素数にも同じような制限があるはず.


ただ, #2 の最後にもちょろっと書いたけどそれとは無関係で #3 にいわれる排他制御の問題だと思いますよ. 「競合はしていませんでした」と書かれていますが, 「複数人が (ほぼ) 同時に掲示板に書き込む」状況を想定して調べましたか?
ああ, もう 1つ「遅延書き込み」という問題もあり得るか. 「同期書き込み不可能」とかいう腐った OS だと考えられなくもない.

この回答への補足

たびたびありがとうございます。

やはり聞く限り、2ギガビットとか全然行ってないですし、その辺の容量オーバーは
違う感じですね。排他制御ですが、本に書かれていたロックをかけるやり方をしていた
だけです。回答番号:No.3の補足にその部分を載せました。
同時書き込みや非常に重い時にも大丈夫かと言われると、flock に任せているだけで
少なくともテストはしていませんし、実行環境もそんな混み合ってはいませんでした。
そういう状況に耐えうる堅牢なロジックがあるなら念のため入れ替えておきたいところです。
でもその前に今回のデバッグですね・・・・・・。

補足日時:2010/06/30 02:22
    • good
    • 0

ファイルの排他制御に失敗した可能性が高いんじゃないかと思います。


2つのプロセスが同時に書き込んだりしたら、例えば、
あるプロセスが書き込んでいる途中のタイミングで、次のプロセスだデータ読み込みを実行
   →書き込み途中までのでデータしかしか読み込めない
ということになります。その後、最初のプロセス側では書き込み完了すれば、ファイルは正しい状態になりますが、

後のプロセス側で読み込んだデータは、その中途半端に読み込んだ壊れた状態になっているので、
後のプロセス側が書き込みを行えば、ファイルが壊れた状態に更新されることになります。

排他処理はファイルサイズに依存した問題ではありませんが、
ファイルサイズが大きくなると読み書きに時間がかかるようになるので、
タイミング的に問題が発生する確率は高くなります。

この回答への補足

回答ありがとうございます。

書き込み処理を行っている部分のソースを、回答番号:No.3 さんへの補足に載せました。
詳しく知識があるわけではありませんが、「flockでロックしているから大丈夫」、
という認識でした。解説本にもそうあったと思います。
それで、それがデータサイズが大きすぎて時間がかかった時とかのイレギュラー時の
処理なんですよね。。。

補足日時:2010/06/30 02:15
    • good
    • 0

ファイル読み書き時の排他制御が適切でなかった場合によく起こる症状に見えます。


flock()などでファイルロックをかけるのが一般的な排他制御ですが、書き込み時にopen(HANDLE, '>', ...)で新規書き込みオープンしてしまうのが最も典型的なミスです。
この場合、ロックがかかる直前に他のプロセスから読み込み処理が行われると空ファイルが読まれてしまうので、意図した動作にならずにファイル内容が失われる恐れがあります。
読み込み/書き込みのファイルオープン・クローズ処理に問題がないか確認されてはいかがでしょうか。
該当部分のスクリプトを公開して頂ければ、具体的なアドバイスが出来ると思います。

この回答への補足

回答ありがとうございます。
取り急ぎ書き込み部分を載せます。紙谷歌寿彦氏の本のやり方だったと思います。


$WriteComment
に今回の書き込みデータが入っている状態です。


# ファイルの追加書き込み処理
open( WRITE, "+< ../data/bbs.dat" );# 開く
flock( WRITE, 2 );# ロック
@OldBbsData = <WRITE>;
unshift( @OldBbsData, $WriteComment );
truncate( WRITE, 0 );# サイズを0に変更する(消す)
seek( WRITE, 0, 0 );# ファイルのカーソル位置の変更
print WRITE @OldBbsData;
close( WRITE );

補足日時:2010/06/29 13:56
    • good
    • 0

「ファイル容量の制限」は OS やら設定やらによるけど Perl は無関係.


「変数の容量制限」は, 「Perl言語」としては「int の大きさ」が影響したはず. あと, 当然だけど「1つのプロセスで使うことのできるメモリ量」にも依存する. だから, Perl処理系に (この辺の) バグがなければ 1.5 MB くらいでは死なない.
手元では Perl 5.10.1 だけど,
$a = join('', 'a' .. 'z') x 1000000;
くらいならまったく問題なく動きます.
ファイルの読み書きで競合しているって可能性はないか?

この回答への補足

回答ありがとうございます。

ファイルハンドラを見てみましたけど競合はしていませんでした。
ずっと問題なく動いていたんですよね。それでいきなり壊れたので
「ついに処理できる容量が限界を超えた」のかと思ったのですが。

「ファイル容量の制限」は違うんですね。
となると変数かメモリなのですが、変数の「intの大きさ」というのは
どの部分のことでしょうか? 
書き込みデータ処理には、変数や配列を使っていますが結構そのまま
ガンガン入れている状態です。

補足日時:2010/06/29 12:00
    • good
    • 0

変数なら、型により長さが規定されているでしょうね。


型で規定されている長さを超えるとダメでしょう。
Perl5.6.1 言語の仕様では?

この回答への補足

回答ありがとうございます。

型は……、ないです(よね?)。
その仕様がちょっと見つけられなくて。
今、教えてgoo内で「文字数の規定はありません」と答えている回答を
見つけました。メモリ関連は影響するようです。

補足日時:2010/06/29 11:48
    • good
    • 0

このQ&Aに関連する人気のQ&A

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人はこんなQ&Aも見ています

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

Q変数に格納できる文字数の限界

お世話になります。
題名の通り、Perlで変数に格納できる文字数の限界は
あるのでしょうか?
100文字くらいの文章を変数に入れることができません。こういった場合はどうしたらいいかアドバイスを頂けませんでしょうか。

$shou=$1 if/\{第1章\}(.*?)/;
というように{第1章}に続く文章(大体100字くらい)を抽出して、それを変数に入れたいのですが、
$shouを表示させようとしても何も表示されません。
どうぞよろしくお願いします。

Aベストアンサー

#2 です。

力技ですが。。

in_data.txt
{第1章}
aaaaaaaaaaaa。\\bbbbbbbbb
ccccccccccccccccccc。\\
{第2章}
ddddddddddddddd。\\eeeeeeeeeee
fffffff。\\ggggggggggggggggggggggggggg。\\

スクリプト
#!/usr/local/bin/perl

$fin = "in_data.txt";
$s = "";
@t = ();

# ファイルを読み込みつつ、@tへ取り込む
open(IN, $fin) or die "open error.";
while(<IN>) {
chop;
if ($_ =~ /{第(\d+)章}/) {
$s = $1;
}
else {
$t[$s] .= $_;
}
}
close(IN);

# テスト表示をする。
for $i (0 .. scalar(@t)-1) {
if ($t[$i] ne "") {
print "第${i}章\n";
print $t[$i]. "\n";
}
}

結果
第1章
aaaaaaaaaaaa。\\bbbbbbbbbccccccccccccccccccc。\\
第2章
ddddddddddddddd。\\eeeeeeeeeeefffffff。\\ggggggggggggggggggggggggggg。\\

って感じになりました。
このスクリプトでは、章番号をキーとした配列 @t を作り、
その中に取り込んでいます。

目的は、こんな事でしょうか?

#2 です。

力技ですが。。

in_data.txt
{第1章}
aaaaaaaaaaaa。\\bbbbbbbbb
ccccccccccccccccccc。\\
{第2章}
ddddddddddddddd。\\eeeeeeeeeee
fffffff。\\ggggggggggggggggggggggggggg。\\

スクリプト
#!/usr/local/bin/perl

$fin = "in_data.txt";
$s = "";
@t = ();

# ファイルを読み込みつつ、@tへ取り込む
open(IN, $fin) or die "open error.";
while(<IN>) {
chop;
if ($_ =~ /{第(\d+)章}/) {
$s = $1;
}
else {
$t[$s] .= $_;
}
}
close(IN);

#...続きを読む

Qperl 配列の要素数について

配列の要素数について質問させていただきます。

プログラムの中で、以下のようにファイルの内容を1行ずつ読み込み、配列に入れています。
 open (IN, "ファイル名");
 @data = <IN>;
 close (IN);
こういった形で配列に入れていった場合、入れられる最大行数(=最大要素数)はどれくらいになるのでしょうか。
現在100万行のテキストファイルは、問題なく読み込めているようでした。

ご存知の方がおられましたら、ご回答いただければと思います。
よろしくお願いいたします。

Aベストアンサー

おそらく、メモリの使用制限次第だと思います。

ただ、通常そのような大量のデータ処理の場合は、メモリになるべく溜め込まないような設計にすべきですので、whileなどをうまく使って個々に処理をしてメモリを解放してあげる構成にしたいものです。

Q数値かどうかの判定方法

$aに代入されているものが数値かどうかを判定するにはどのようにしたらよいのでしょうか?

Aベストアンサー

$a =~ /^[0-9]*$/
上記の場合、*は「直前のパターンの0回以上の繰り返し」の意味なので、0から9がなくても、つまり$aが空でもマッチしてしまいます。
なので、
$a =~ /^[0-9]+$/
としましょう。
(+は「直前のパターンの1回以上の繰り返し」)
また、0-9は\dで表すこともできるので
$a =~ /^\d+$/
と書くこともできます。

QCan't use string ("0") as an ARRAY ref の原因について

Perl 5.6を使っております。
Perlで原因不明なエラーに直面して困っております。
Can't use string ("0") as an ARRAY ref while "strict refs"
というエラーが発生しているのですが
これは良くあるミスとして何が原因でしょうか?

Aベストアンサー

No.2です。書き漏らしてましたが、エラーメッセージの内容がよくわからない時は

use diagnostics;

しましょう。

Qひとつの命令を複数行に記述

検索してもあまり解説見かけないなぁと思うのですが、(どこが本家かわからないのでとりあえず放置)

VBでいう_に該当するものは何ですか?
ソースが長くなって見にくくなっているので、対処したいのですが。

hoge = "じゅげむじゅげむごごうのすりきれ" _ '←次の行に送る
& "かいじゃりすいぎょのうんらいまつふうらいまつすいぎょうまつ" 

Aベストアンサー

Perlは、VBと異なり行の概念がありません。
VBではステートメント区切り子が存在しないため、改行がステートメントの区切りとして扱われ、例外的につなげるときに「_」を使うわけですが、
Perlの場合はステートメント区切り子セミコロン「;」がステートメントの区切りになっていますので、セミコロンを打たない限り、何行に分かれてもひとつのステートメントとして扱われます。
したがって、回答としては「そのまま改行してOK」です。
上記の例なら、

$hoge = "じゅげむじゅげむごごうのすりきれ" .
"かいじゃりすいぎょのうんらいまつふうらいまつすいぎょうまつ";

という感じです。
当然ながら、文字列中での改行はダメなので、上記のようにいったん「"」を閉じて、文字列結合演算子「.」で接続することに成ります。

Qperlで容量の大きいCSVファイルを開く方法

perlで容量の大きいCSVファイルを開く方法


ファイル容量の大きいcsvファイルから、必要な項目を抜き出して別ファイルにするプログラムを作成したいと思ってます。
csvファイルが少ない場合は動作したのですが、容量が140MBを超えたデータを読み込もうとすると、ブラウザー表示で何も変化いたしません

プログラムは以下のようになってます。
-------------------------------------------------

open(IN,"$inport") || &error(" $inport を読み込みopen出来ません");
flock(IN,1);
@lines = <IN>;
foreach $lines (@lines) {
local(@val) = split("\,", $lines);
print "$val[0]";
$dat .= "$val[1]\,$val[5]\n";
}
open(OUT,">$dcsv");
flock(OUT,2);
print OUT "$dat";
close OUT;


-------------------------------------------------
件数も多いので、foreachを$lines (@lines) としないで($start .. $end)として読み込みの件数を制限して対応しようと考えてましたが、うまくいきませんでした。

ご指導いただけますと幸いです。

perlで容量の大きいCSVファイルを開く方法


ファイル容量の大きいcsvファイルから、必要な項目を抜き出して別ファイルにするプログラムを作成したいと思ってます。
csvファイルが少ない場合は動作したのですが、容量が140MBを超えたデータを読み込もうとすると、ブラウザー表示で何も変化いたしません

プログラムは以下のようになってます。
-------------------------------------------------

open(IN,"$inport") || &error(" $inport を読み込みopen出来ません");
flock(IN,1);
@lines = <IN>;
foreach $l...続きを読む

Aベストアンサー

質問者さんのコードは
> @lines = <IN>;
ここで、ファイルの全データを変数に読み込んで
> foreach $lines (@lines) {
これで、データを1つづつ取り出す

という処理になっていますので、「@lines=<IN>」の時点でメモリを大量に消費します。この2行の代わりに


> while ($lines = <IN>) {

とすれば、ファイルから1行ずつデータを読んで処理するようになりますので、
ファイルサイズが大きくても処理できるようになります。

ただし、そうやったとしても、
> $dat .= "$val[1]\,$val[5]\n";
この部分で変数 $dat のサイズがどんどん大きくなりますから、そちらの分のメモリ消費は入力ファイルサイズに比例します。

---

open(IN,"$inport") || &error(" $inport を読み込みopen出来ません");
flock(IN,1);

open(OUT,">$dcsv");
flock(OUT,2);

while ($lines = <IN>) {
local(@val) = split("\,", $lines);
print "$val[0]";
print OUT "$val[1]\,$val[5]\n";
}
close IN;
close OUT;
---
とすれば、完全に入力ファイルサイズに依存しないようになります。

質問者さんのコードは
> @lines = <IN>;
ここで、ファイルの全データを変数に読み込んで
> foreach $lines (@lines) {
これで、データを1つづつ取り出す

という処理になっていますので、「@lines=<IN>」の時点でメモリを大量に消費します。この2行の代わりに


> while ($lines = <IN>) {

とすれば、ファイルから1行ずつデータを読んで処理するようになりますので、
ファイルサイズが大きくても処理できるようになります。

ただし、そうやったとしても、
> $dat .= "$val[1]\,$val[5]\n";
この部分で変数 $dat ...続きを読む

Q正規表現で囲まれた部分の文字列

正規表現でダブルコーテーションで囲まれた部分の文字列
を検索したいのです。
\"([^\"])*\"
とりあえずこんな感じで検索はできるのですが
問題はダブルコーテーションで囲まれた部分の
エスケープ文字\の判定が上手くできません。
([^\"])
この部分でダブルコーテーション以外の文字列、
ただし\"は除くって感じにしたいのですがどうすれば良いでしょうか。
宜しくお願いします。

正規表現のエンジンはBREGEXP.DLLです。
http://www.hi-ho.ne.jp/babaq/bregexp.html

Aベストアンサー

([^\"])

(\\\"|[^\"])
としたらでどうでしょうか。

QRed Hat 7.1 に rshできない(~/.rhostsの設定後)

Red Hat Linux release 7.1 です。
~/.rhosts を設定しても 他及び自ホストから rshできません。
ホストとユーザを記述し,モードを 600 にしました。

どうすれば,rshを許可できるでしょうか?

Aベストアンサー

myhost: Connection refused
で拒否されるのであれば、
inetd/xinetdからin.rlogindの起動が
許可されていません。
inetd(スーパーサーバ)の関連を、調べなおして
見ましょう。
TCP Wrapperで拒否されたのであれば
Connection reset by peer.
と表示されます。

プロンプトから
ps -ax|grep inetd|grep -v grep
と入力し、inetdとでたら、/etc/inetd.conf
のloginで始まる行のコメントを解除しましょう。
ファイルを、

xinetdと表示されたら/etc/xinetd.d/rlogin
を修正しましょう。
disable = yes
となっているはずです。これをnoに変えましょう。

単にリモート操作をしたいのであればrloginやtelnet
の方が適していると思います。rshは遠隔でコマンドを
実行するのが目的でリモートログインするのは
おまけ的な要素でしかありません。
なぜrshなのでしょうか?
何もrshでなくてtelnet/rloginでは何がだめなのでしょうか?


注意:
ここでは「単に動くだけ」の設定方法しか紹介して
おりません。そのためこのままではセキュリティ的に
非常に弱いので、このままインターネットに直結/常設
することは避けてください。

myhost: Connection refused
で拒否されるのであれば、
inetd/xinetdからin.rlogindの起動が
許可されていません。
inetd(スーパーサーバ)の関連を、調べなおして
見ましょう。
TCP Wrapperで拒否されたのであれば
Connection reset by peer.
と表示されます。

プロンプトから
ps -ax|grep inetd|grep -v grep
と入力し、inetdとでたら、/etc/inetd.conf
のloginで始まる行のコメントを解除しましょう。
ファイルを、

xinetdと表示されたら/etc/xinetd.d/rlogin
を修正しましょう。
...続きを読む

Qperlでファイルを分割するプログラム

3Mを超える1つのテキストファイルに入っているデータある目印をもとに分割したいと思っています。分割ソフトをさがしたのですが見つけられませんでした(サイズで分割はありました)perlでテキスト処理ができると思い「テキスト処理とCGIのためのPerlプログラミング 伊藤 博康 (著) 」という本を借りてきたのですが、そのようなサンプルがなく1からperlを勉強する時間もないため、ここで質問させていただきました。ネット上にファイルを分割するperlのサンプルプログラムがありましたら教えてください。よろしくお願いします。

Aベストアンサー

 存在しません(^_^;
 簡単に「ある目印」と書かれていますが、その目印はプログラマーの数だけ種類があり、その目印の形によってはプログラム構造自体の変更が必要です。
 読者が欲しい目印の形を先読みしてプログラムを組むのは不可能です。

 どんな目印でしょうか?
 簡単な目印なら、ここにサンプルプログラムを書けるかもしれません。

QPerlで特定行から特定行までを抜き出したい

皆さんのお知恵をお貸し頂ければ幸いです。

Perlで以下のようなことをしたいと考えています。
例えば、次のようなテキストファイルがあったとします。

example.log
==================================
aaaa
hogehoge
test
okok
perl
script
==================================

上記ファイルを読み込んで、「hogehoge」から「perl」の間に挟まれた行だけ抜き出したいのです。
イメージとしては、読み込んだファイルを配列に入れて、一行づつ読ませ、キーワード「hogehoge」が現れたらそこでフラグを立て、それ以降の行を表示し、キーワード「perl」が現れた時点で表示を止めるという処理になるのかな?と思っています。

このような場合、どういう風にすればいいのでしょうか?
恐れ入りますが、ご教授頂ければ幸いです。

それでは、どうぞよろしくお願い致します。

Aベストアンサー

> 一行づつ読ませ、キーワード「hogehoge」が現れたらそこでフラグを立て、それ以降の行を表示し、キーワード「perl」が現れた時点で表示を止めるという処理になるのかな?と思っています。

それでいいと思いますよ?これをそのままコード化すると、こんな感じでしょうか。(No.1さんのとはちょっと結果が違います。)

open FH, "example.log" or die $!;
$flag = 0;
while ($data = <FH>) {
  chomp $data;
  if  ($data eq "hogehoge") { $flag = 1 }
  elsif ($data eq "perl")    { $flag = 0 }
  elsif ($flag) { print "$data\n" }
}
close FH;

で、もっと略したいPerlな人だとこんな感じ。Perl独特の記法がふんだんに使われているので、勉強するには不向きかもしれませんが^^;

open FH, "example.log" or die $!;
while (<FH>) {
  print if /^hogehoge$/ .. /^perl$/ and !/^(?:hogehoge|perl)$/;
}
close FH;

※インデントに全角空白を使っているので、コピーする場合はタブなどに置換して下さい。

> 一行づつ読ませ、キーワード「hogehoge」が現れたらそこでフラグを立て、それ以降の行を表示し、キーワード「perl」が現れた時点で表示を止めるという処理になるのかな?と思っています。

それでいいと思いますよ?これをそのままコード化すると、こんな感じでしょうか。(No.1さんのとはちょっと結果が違います。)

open FH, "example.log" or die $!;
$flag = 0;
while ($data = <FH>) {
  chomp $data;
  if  ($data eq "hogehoge") { $flag = 1 }
  elsif ($data eq "perl")    { $fl...続きを読む


このQ&Aを見た人がよく見るQ&A

人気Q&Aランキング