大ショックです。 jcode.plを最新版(v 2.13 2000/09/29)に入れ替えたら 半角カナを認識しました。それだけのことだったのです。 大解決です。ここまでたどりつけたのも皆様のおかげです。 ありがとうございました。 それから,いろいろと変なことを書いたりやったりして すみませんでした。 ちなみに下に書いた私が使っていたjcode.plのバージョンは, 中に書いてあった記述をそのままコピーして貼ったのですが, ちょっと変ですね(^^; |
思わず,半角カナを認識したと書きましたが,正確には違うようです。 半角カナのsjisとeucは判別しようがないですよね。 中の説明には特に書かれていないようですが, 判別不能な場合の処理として, 古いバージョンではsjisと判断していたところを eucに判断するようにしたのではないでしょうか。 |
どうやら,2.3から2.6にバージョンアップしたときに 修正されたようです。以下,引用です。 (バージョンの記述が変だったというのは私の勘違いでした。) −−−−−−−−−−−−−−−−−−−−− jcode.pl-2.6 をリリースしました。 ftp://ftp.iij.ad.jp/pub/IIJ/dist/utashiro/perl/jcode.pl-2.6 2.3 からの変更点は、以下の通り。 - &jcode'tr の中で JIS コードの認識方法をちょっとだけ変更 - JIS X 0208-1990 のシークエンスを認識するように変更 - &jcode'getcode のバグを修正して、説明を追加 --utashiro |
はじめまして。玉中と申します。 突然の投稿で失礼致します。 1台のパソコンにネットワークカードが複数枚ささっており、それぞれにIPアドレスが割り当てられている場合に、それら全てのIPアドレスを取得するにはどのようにすればよいのでしょうか。言語は C/C++ です。 NIC が1枚だけの場合は、gethostname() と gethostbyname() で取得できるのですが、複数の場合の取得方法が分かりません。 つまりは、ifconfig コマンドのようなことをやりたいのですが、 どなたか方法をご存知ありませんでしょうか。 よろしくお願い致します。 |
UDPクライアントをPerlで作成したいのですが なかなか上手く行きません。 特定のポート番号(例 NTPの123)にメッセージをなげて そのポート番号が存在するかしないかを確かめたいのですが・・・ どなたか詳しい方いらっしゃいませんか? |
>>2198 SA > 特定のポート番号(例 NTPの123)にメッセージをなげて 送るだけなら、多分こんな感じだったかと。 use Socket; my $iaddr = inet_aton("10.0.0.1"); my $sock_addr = pack_sockaddr_in(123 ,$iaddr); socket(SOCKET, PF_INET, SOCK_DGRAM, 0); send(SOCKET, "hoge", 0, $sock_addr); ただし、 > そのポート番号が存在するかしないかを確かめたいのですが・・・ UDP なので、送ったデータが相手側に到達したかどうかは 判別できません。 >>2197 玉中 > つまりは、ifconfig コマンドのようなことをやりたいのですが、 ioctl & SIOCGIFCONF でやるか、BSD 系なら getifaddrs(3) ってのが 使えるはずです (OS 名くらい書きましょう)。どちらも http://www.mmjp.or.jp/pearsoned/washo/network/wa_net28-j.html の16章に載ってます。 あとは ifconfig のソースなどを参考にして下さい。 http://www.jp.FreeBSD.org/cgi/cvsweb.cgi/src/sbin/ifconfig/ |
>>2184 68user >> @a[0] はスライスです。 > ん〜、(@a)[0] とは違うということですか? どちらもスライスだと思うのですが @a は配列のスライスで, (@a) はリストのスライスかと… ただし, どちらも一般的には「配列スライス」で括られると思います。 要は, 単数であっても配列やリストの添え字であった場合には スライスと呼べるだろうという個人的解釈です。 # ↑突っ込み大歓迎モード |
AGEと申します。 Red Hot Linux 7.0J を使用しています。 「ntp-4.1.0.tar.gz」をインストールしてみました。 しかし、rpm のものがあったのでアンインストールしたいのですが インストールされたファイルを知る方法はあるのでしょうか? よろしくお願いいたします。 |
>>2191 68user ServletもCGIと同じくリクエスト毎に起動するのですか? 不勉強でした。セッション管理ができると言うので常駐するものと 勘違いしていました。 >パズルのようにプログラムを組み上げて行く感じです。 そのパズルが難しそう(^^; >>2201 AGE >インストールされたファイルを知る方法はあるのでしょうか? man rpm をどうぞ。 ntpってRHLに標準で入っている(はず)の xntpdとは別物なんですね。 |
>>>2202 スナフキン >man rpm をどうぞ。 すいません。言葉足らずでした。 xntp はインストールされてなかったので、 ntp はソースから make install しました。 その場合のインストールされたファイルを知りたかったのです。 ntp を削除して、管理しやすい xntp(ntp-4.0.99-15〜.rpm)を インストールしようとおもってます。 |
ええと,結局,最新版jcode.plでも半角カナは文字化けしました。 たまたま「シイ」はOKでしたが「アイウエオ」はNGでした。 こちらの掲示板でもたぶん化けると思います。 そこで,前に書いた方法をスクリプトにしてみました。 尚,送信ページには,↓この1行が入っています。 <INPUT TYPE="hidden" NAME="assist" VALUE=" "> VALUEは,全角スペース5個です。 −−−− # コード判別補助文字列名(送信ページと統一,半角英数字に限る) $assi = 'assist'; read(STDIN,$input,$ENV{'CONTENT_LENGTH'}); @parts = split(/&/,$input); # コード判別補助文字列$ASSIST0の取得 foreach(@parts) { ($key0,$val0) = split(/=/); # 最初の=で分離 $key0 =~ s/%([0-9a-fA-F][0-9a-fA-F])/pack("C",hex($1))/eg; if ($key0 eq "$assi") { $ASSIST0 = $val0; } } foreach(@parts) { ($key,$val) = split(/=/); # 最初の=で分離 $val =~ tr/+/ /; # trは1文字単位の置換 # コード判別補助文字列の追加 if ($key ne "$assi") { $val = $val.$ASSIST0; } $key =~ s/%([0-9a-fA-F][0-9a-fA-F])/pack("C",hex($1))/eg; $val =~ s/%([0-9a-fA-F][0-9a-fA-F])/pack("C",hex($1))/eg; jcode::convert(\$key,'euc');#---- from jcode.pl jcode::convert(\$val,'euc');#---- from jcode.pl if ($key eq "$ass") { $ASSIST = $val; } $val =~ s/($ASSIST)$//g; # コード判別補助文字列の除去 $key =~ s/\r\n|\r|\n//g; # gはマッチする文字全て $val =~ s/\r\n|\r|\n//g; $key =~ s/,/,/g; $val =~ s/,/,/g; $key =~ s/</</g; $val =~ s/</</g; $key =~ s/>/>/g; $val =~ s/>/>/g; $key =~ s/"/”/g; $val =~ s/"/”/g; $key =~ s/&/&/g; $val =~ s/&/&/g; $in{$key} = $val; } −−−− これで「ア」などという1文字の半角カナもコード判別できているようです。 もうちょっとスッキリできればいいのですが……。 |
>>2204 shii http://www.din.or.jp/~ohzaki/perl.htm#JP_Code っていうかそのコードには 気になる点がいろいろと・・・ |
>>2205 ナナシサソ リンク先はPerlメモのgetcode関数のところですね。 できれば気になる点を具体的に指摘していただけると とてもありがたいのですが。 |
>>2204 shii 考え方はよいのですが、もちっとスマートにやるなら、 「あ」の文字コードを調べるスクリプト require 'jcode.pl'; $_="あ"; jcode::convert(\$_, 'euc'); s/(\W)/sprintf("%%%02X", unpack("C", $1))/eg; print "あ in euc-jp: $_\n"; $_="あ"; jcode::convert(\$_, 'sjis'); s/(\W)/sprintf("%%%02X", unpack("C", $1))/eg; print "あ in shift_jis: $_\n"; $_="あ"; jcode::convert(\$_, 'jis'); s/(\W)/sprintf("%%%02X", unpack("C", $1))/eg; print "あ in jis: $_\n"; 実行結果: あ in euc-jp: %A4%A2 あ in shift_jis: %82%A0 あ in jis: %1B%24B%24%22%1B%28B # これは他のパターンも有りうるかも を踏まえて、 <input type="hidden" name="assist" value="あ"> としておき、 read(STDIN,$input,$ENV{'CONTENT_LENGTH'}); ($assist_code) = $input =~ s/(^|&)assist=(.*?))($|&)//; if ( $assist_code =~ m/^\%A4\%A2$/i ){ $input_encoding = 'euc'; } elsif ( $assist_code =~ m/^\%82\%A0$/i ){ $input_encoding = 'sjis'; } elsif ( $assist_code =~ m/^\%1B\%24B\%24\%22\%1B\%28B$/i ){ $input_encoding = 'jis'; } @parts = split(/&/,$input); foreach(@parts) { ($key,$val) = split(/=/); $key =~ s/%([0-9a-fA-F][0-9a-fA-F])/pack("C",hex($1))/eg; $val =~ s/%([0-9a-fA-F][0-9a-fA-F])/pack("C",hex($1))/eg; jcode::convert(\$key,'euc', $input_encoding); jcode::convert(\$val,'euc', $input_encoding); } くらいがよろしいかと思います (動作確認はしていません)。 >>2203 AGE > ntp はソースから make install しました。 > その場合のインストールされたファイルを知りたかったのです。 もし Makefile に uninstall とか deinstall とかいうターゲットがあるなら、 # make uninstall # make deinstall ですが、なさそうならば # make -n install して、インストールされるファイルをメモって、手動で rm ですね。 >>2202 スナフキン > ServletもCGIと同じくリクエスト毎に起動するのですか? いいえ、しません。そういう意味では常駐していますね。 しかし、CGI を使うときも apache が常駐していますが、「常駐 システムを開発している」という意識は僕にはありません。それと 同様に、Servlet コンテナが常駐していても「常駐システム」とは 呼ばないんじゃないなぁ、ということです。まぁ、ここらへんの 感覚は人によって違うのかもしれません。 >>2200 /tk > どちらもスライスだと思うのですが えっと、@a[0] と (@a)[0] は違うんですよね? ということです。 要は、 「@a[0] は文法エラーのところを perl があえて $a[0] に読み変えている」 とこれまで思っていたのですが、 「@a[0] は文法的には正しいけれど、$a[0] の方が適当なので perl があえて警告するようにしている」 ということでしょうか? > @a は配列のスライスで, (@a) はリストのスライスかと… perl に配列とリストという区別はあるんでしたっけ。 |
>>2207 68user おお,なるほど!ありがとうございます。 ダミーを送るのなら,それをわざわざ対象文字列に結合しなくても いいわけですね。私が間抜けでした。 文字コードを調べるスクリプトが面白いですね(勉強になります)。 今回の件を自分のCGI向けに最小限にカスタマイズした(つもりの) スクリプトが下記です。 #--------------------------------------------------------- read(STDIN,$input,$ENV{'CONTENT_LENGTH'}); @parts = split(/&/,$input); foreach(@parts) { ($key,$val) = split(/=/); $val =~ tr/+/ /; $key =~ s/%([0-9a-fA-F][0-9a-fA-F])/pack("C",hex($1))/eg; $val =~ s/%([0-9a-fA-F][0-9a-fA-F])/pack("C",hex($1))/eg; $code = &jcode::getcode(\$key); jcode::convert(\$key,'euc',$code); jcode::convert(\$val,'euc',$code,"z"); $val =~ s/\r\n|\r|\n//g; $val =~ s/,/,/g; $in{$key} = $val; } #--------------------------------------------------------- 入力項目名に半角カナ以外の日本語を使用することが前提なので, 汎用性はありません。 getcode関数を全項目に使っているところが余分なのですが, 見た目は,以前に比べてすっきりしました。 ところで, > ($assist_code) = $input =~ s/(^|&)assist=(.*?))($|&)//; ここはassistの中身のみを残して残りを消す作業だと思うのですが, ($assist_code)にカッコがついている理由と, 正規表現内のカッコの数が合わない理由を教えてください。 ・「行の先頭」または「&の直後」にある「assist=」 ・「任意の1文字の0回以上の最短マッチ」 ・「行の終わり」または「&の直前」 と,部分的にしか理解できませんでした。 |
>>2208 shii おいらはこう書くべきと思うけどな my ($assist_code) = $input =~ /(?:^|&)assist=([^&]*)/; どうせassist=なんじゃら、なんて残ってたって関係ないし。 > 正規表現内のカッコの数が合わない理由を教えてください。 ミスだねこれは だいたい、これだと > ($assist_code) = $input =~ s/(^|&)assist=(.*?))($|&)//; $assist_codeに入るのは(^|&)の部分になっちゃう |
>2207 68user >もし Makefile に uninstall とか deinstall とかいうターゲットがあるなら、 > # make uninstall これでうまくいきました。ありがとうございました。 |
メールを送るCGIについて。 フォームに入力されたメールアドレスに対して、Sendmailを使って CGI(Perl)からメールを送る時のことです。 ユーザやホスト名などが間違ったメールアドレスを入力しても、外部の サーバ宛てなら、正常にCGIが終了し、エラーメールが戻ってきます。 ここまでは良いのですが、CGIやSendmailがあるサーバと同じサーバ 宛てにメールを送る場合、アドレスが正しければもちろん正常にCGI は終了し、メールは届きますが、UserUnknownになるようなメールアド レスを指定して送ると、正常にCGIは終了せず、サーバエラーになっ てしまいます。 このようなサーバエラーを回避する方法はあるのでしょうか? どなたか教えて下さい。よろしくお願いします。 |
初めましてpearlともうします。 以下のことで大変困っており、この掲示板にたどり着きました。 どうぞアドバイスをよろしくお願いします。 NTサーバーのあるディレクトリ(aaa)以下の 複数のサブディレクトリ(x1,x2,x3...)にある全てのファイルを 階層構造を保ったまま、Solarisのあるディレクトリにそっくり 移動(転送)したいのです。操作できるのは、Solaris側のみで、 シェルスクリプトによる自動実行を目指しております。 当初は、ftpのオプションで簡単に出来ると思っておりましたが・・。 また、不定期にサブディレクトリおよびファイルの追加があり 出来得るならば、初回以降は差分ファイルの転送だけ行いたい のですが、実現可能な方法をどなたかご教示願えませんか? |
>>2209 ナナシサソ > おいらはこう書くべきと思うけどな そうですね、僕の書いたコードではうまく動きませんでした。 >>2211 ぷよ丸 要はエラーを無視できればよいのですか? 何もエラー処理を 考えずに書けば無視できるのではないかと思うのですが、 具体的にどのように sendmail を実行していますか? >>2212 pearl おそらくは rsync を使うのがベストではないかと思います (使った ことはありませんが)。それがダメなら wget かなぁ。あるいは Solaris に sharity-light を入れて SMB しゃべれるようにして、 NT 側は共有フォルダ (って言うのかな) にしておくとか (これも 使ったことはありません)。 |
「エラー処理を無視できれば・・・」で、ひらめいて、エラーログ を見ながらいろいろとやってると解決できました。 つまり、sendmailでメールを送るときに、同一サーバ宛てのメー ルアドレスが間違っていると、標準出力にUserUnknownのエラーが 書き出され、HTML出力前にそうなるから、エラー(BadHeader のエラーかな?)になっていたんですね。 それが分かったので、HTMLを先に出力してから標準出力を閉じ、 sendmailでメール送るという順序にすることで解決しました。 これだと、sendmailの実行時にエラーが出てもCGIからは無視し た感じになりますものね。 めでたしめでたしで解決したので報告します。 コメントありがとうございました。 これからもよろしくお願いします。 |
>>2207 68user > 要は、 > … cut … > ということでしょうか? そういう事だと思います。 以前書いた時に記述した近藤さんのサイトにも > @a[0]のような書き方はPerlのコードとして正しいものだからです。 と書かれていますし。 > perl に配列とリストという区別はあるんでしたっけ。 ん〜, スカラーで評価した時に, 配列は要素数を返し リストは最終要素を返す。 とかそういう話ではなくてでしょうか? でも, scalar (@a); とか書いたら, しっかり最終要素が吐き出されたので なんか, 自分でも @a と (@a) の違いはよくわかりません。 少なくとも > えっと、@a[0] と (@a)[0] は違うんですよね? はい。そうです。 とは言えなくなってしまいました。 # 読み返すとゴミのような発言ですが, ご容赦下さい。m(_ _)m |
訂正です。 >>2215 /tk > 最終要素が吐き出されたので 要素数が吐き出されたので |
はじめましてです。 『HTTPクライアントを作ってみよう』の辺を参考にHTTPクライアントを 作っているのですが、うまくいきません。 まず、”作ってみよう”の前にtelnetを使ってのところでつまずきました。 % telnet test.hoge.com 80 Trying 123.123.123.10... Connected to test.hoge.com. Escape character is '^]'. GET /test/test.html HTTP/1.0(リターン) とやると、『NOT FOUND』になってしまいます。 ※ブラウザでhttp://test.hoge.com/test/test.htmlは表示される。 ※ちなみに、http://123.123.123.10/test/test.htmlは『NOT FOUND』 おそらく、Apacheでヴァーチャルホストで設定しているのだと 思いますが、このような場合どのようにすればよいのでしょうか? 以上 宜しくお願いいたします。 |
>>2217 QDAK GET / HTTP/1.0(改行) Host: test.hoge.com(改行) (改行) |
>>2207 68user 「常駐システム」という言葉が悪かったですね、訂正します。 >Servlet コンテナが常駐して あえて言えば mod_perlに近いのでしょうか? まあ、そのうちに勉強して理解できるように頑張ります。 #なかなか時間が取れませんが… >>2217 QDAK ナナシサソ(舌を噛みそう(^^;)さんも書いていますが、 http://X68000.startshop.co.jp/~68user/net/http-4.html の「さらなる改善点・バーチャルホストに対応」をどうぞ。 |
>2213 アドバイス有り難うございました。検討した結果使うことは出来ませんでしたが大変勉強になりました |
はじめまして。 「UNIXの部屋」でコマンド集を ”かなり”の量コピーさせていただきました。現場用サブnoteに保存して活用いたします。 また何か困ったことがあればここに来ると思いますがそのときはよろしくお願いします。 ありがとうございました。 |
crontab -e user でcronを登録したのですが起動するときにどうも環境設定が user で ログインした状態と違うみたいです。 .cshrc を取り込まずに cron が 動いてるらしくパスやら環境変数やらまるで違うのです。 そこで以下のようにむりやり設定するようにしたのですが 35 18 * * * setenv LANG ja;setenv ・・・ 結果は駄目でした。 cronが起動される際の環境設定(環境変数やパス)はどこでどうやって 設定するのか分かりますか? |
下記No.2222 は解決したので無視してください。 申し訳ありません。 |
1./usr/local/reg/env/.cshrc.sun中で設定され ている a-e, l, m で始まる alias を実際の file に基づき説明 せよ(Mule の複数バッファの機能やカット,ペーストの機能を利 用すると良い). 2.ヒストリ機能で直前のコマンドを少し変更する方法を 調べろ.(cp foo bar と入力する代りに cp ffo bar と入力して しまった場合等に便利) 3.*等のグロッビング用の文字を普通に入力するための方法を 調べろ(ファイル名が * のものを作成せよ.ただし,Mule は使 用しない.set noglob もしない). 4.(t)csh において,~ は特別な意味を持つ文字である.この意 味を調べろ(複数あるかもしれない). (参考)Emacs には,shell という関数や manual-entry という関数が存在する. 1〜4 に対する回答を,Subject が Report 5 なる mail で, 10/25(木)までに ip-rep@j-lab.ee.aoyama.ac.jp に送ること. |
No.2224は学校の課題なんですが、メールは送らないでください。このアドレスは先生のなので、意味がないのです。僕は生徒で、答えがわかったら掲示板に書いてください。お願いします。 |
「掲示板に書いてください。」って・・・ 日本語の勉強が先だよな・・ 先生に苦情を送っちゃっていいですか? |
どうもすいませんでした。昨日からずっとインターネットで調べていたのですが、解らなかったので甘い考えでした。でも、自力でやって、二番だけわかったんですよ。やっぱりだめですよね楽しようとしたら。お返事まってます。 |
でも、愚痴を言っていいですか?先生って授業でやってないことを、レポートにすゆんですよ!!パソコン初めてやってるひとにっとっては、とっても大変なんですよ。学校には聞ける友達もいないし・・・どうしたら・・って考えたら、エキスパートに聞くのが一番かなって!でもいつも徹夜とかでやっても、間違ってると零点にするんですよ!努力を認めてくれないんですよ。ナナシサソさんは、UNIXできる方なんですか? |
ちなみに、二番のこたえは、 「Ctrl-P(以下C-p)を押すとhistoryの前に入力したコマンドが現れる直前に入力 したコマンドをcp foo bar と入力する代りに cp ffo bar と入力して しまった場 合には、C-pを押してcp ffo barのffoをoffと書き換えればよい。」 であってますかね。よろしければ、採点のほうよろしくお願いします。 |
>>2229 n > 学校には聞ける友達もいないし・・・ UNIX を勉強するより、 - 詳しい友達を見付ける。 - それほど親しくない友達でも、課題提出前くらいは親しげに話しかけられる ような社交性を身につける。 - 課題だからといって、問題をそのまま掲示板に書き込んでも反感を買うだけ、 ということを書き込む前に推測できるようになる。 - 仮に課題だとしても、そうは見えないようにうまくカムフラージュ できるような文章力を身につける。努力しているという姿勢を アピールする。 といったことを学ぶべきじゃないですかね。いや、ほんとに。 というわけで、 http://cocoa.2ch.net/unix/index.html あたりで再チャレンジしてみては。 |
どうもご迷惑をかけました。ひとつお願いがあります。これからは、ホントに解らない事だけを聞くので、これからもこの掲示板に書き込みたいのです。よろしくお願いします。68USERさん本当にアドバイスありがとうございます。これからは、気おつけます。これからもよろしくお願いしますと、言いたいのですがいいですか?ダメでしたら素直に書き込みはやめます。ちなみに、今回いのレポートは二番だけで送りました。くどいようですが、すいませんでした。そして、ありがとうございます。 |
「ネットワークプログラミングの基礎知識」で勉強させていただきました。とてもわかりやすくて入門にはピッタシカンカンでした。 難しかったのは、ソケットからの入力のバッファリングをOFFにする部分。以下のような説明をされてましたね。 > 26: select(SOCKET); $|=1; select(STDOUT); >ソケットに対してバッファリングしないようにします。 >これもおまじないだと思って下さい。 なかなかこれを理解できずにいたのですが、「プログラミング Perl 2nd」P146によると >autoflush HANDLE EXPR という関数があるらしいですね。"use FileHandle;"宣言が必要ですが・・。 autoflush SOCKET 1 ↑これなら、"おまじない"じゃなくて意味が通じ易くなるかもしれませんね |
おまじないというと、現時点で目先の理解の妨げになるから今はわからなくていいみたいな意味で書籍などでも使われてると思うので意味を通じさせるつもりは無いと思うんですよね。 説明が面倒(できない)でおまじないと言ってるわけじゃないですから。 でも、おまじないと言われて「ここでおまじないするのか」と素直に理解する人もあんまりいないですよね。 こういう時が、自分で調べ初めて自分で答えを見つける習慣を身に付けるチャンスになってるとおもうので良い表現だと思いますが。 |
>>2233 りょうすけ >説明が面倒(できない)でおまじないと言ってるわけじゃないですから。 ええ。そうですよね。"おまじない"という表現に異論はありません。枝葉の部分まで細かく説明するとかえってわからなくなっちゃいますもんね。 まぁ、プログラムの可読性という面でいうとautoflushも明快で良いかな?と思っただけです。(でも動作の仕組みを理解するにはselectでファイルハンドルを操作したほうが勉強になるのかも・・) |
こんにちは。 http://x68000.startshop.co.jp/~68user/net/rfc.html から リンクして頂いているThe WAYというサイトの管理人です。 このたび、RFC2616の日本語訳のURLが http://www.studyinghttp.net/rfc_ja/2616/ に変更いたしました。 是非リンクの変更をよろしくお願いします。 |
UNIX プログラミング FAQのサイトが http://www.adl.rd.nacsis.ac.jp/~moro/unix-programmer/faq-j_toc.html に移転しているようです。 |
また質問ですいません。 ActiveState 以外の Windows 用 Perl で、 自由に配布できるものってなにがおすすめでしょうか? 友人が自費出版本に CD-ROM を付けて売りたいのですが、 ActivePerl のライセンスがやたら面倒くさく、 (なんか 20 ページの英語の書類を書いてどうこう、、という、 手続きぐらいしろよって話なんですけど) なんとかならないか、という話です。 勝利条件としては ・Perl 5.005 移行で ・Windows で動き ・Jcode.pm が動く ということらしいです。 DJGPP 版、というのもあるようですが、 DOS 用ということで 16bit ですよね。 制限きついのかな、、? Cygwin はぁ、、? と聞いてみましたが、 Cygwin はその説明(bash の説明とか)だけで本1冊書かないといけない、 そうです。(そうかぁ、、?) でも cygwin.dll だけあれば Perl は動くのかな? (そういうインストーラー作れるかな?) (そんな部分的な部分を再版しても Cygnus 的に大丈夫なのかな?) もしご存知の方がいらっしゃればご教示ください。 LSI-C とか Borland C++ のフリー版とかで Perl をコンパイルしてみようかな、、。 |
あーなんかボケボケ書いたかも、、(DJGPP あたり、、) また落ち着いて謝りにきます、、;;; |
こんにちは Perlについて質問させてください。 %aa=(a=>1,b=>2,c=>3); %bb=(a=>4,b=>5,c=>6); %cc=(%aa,%bb); これでは%cc は a=4,b=5,c=6 のように上書きされてしまいます。 %cc が a=5,b=7,c=9 になるようにするにはどうしたらいいのでしょうか よろしくお願いします。 |
#質問で迷惑掛けてるので答で貢献;;; mo さん、はじめまして。 %aa=(a=>1,b=>2,c=>3); ていうことは、 $aa{a} = 1; $aa{b} = 2; $aa{c} = 3; と同じです。 a = 1; b = 2; c = 3; ではないです。 %aa はハッシュというものを作っています。 お手もとの参考書などで「ハッシュ」という言葉を調べてください。 で、%bb=(a=>4,b=>5,c=>6); ていうことは、 $bb{a} = 4; $bb{b} = 5; $bb{c} = 6; と同じです。 %cc=(%aa, %bb); ということは、上の結果、 %cc=(a=>1,b=>2,c=>3,a=>4,b=>5,c=>6); と一緒なので、 $cc{a} = 1; $cc{b} = 2; $cc{c} = 3; $cc{a} = 4; $cc{b} = 5; $cc{c} = 6; と一緒なので、結局 $cc{a}、$cc{b}、$cc{c} は2回代入されるので、 後のほうが有効になって、 $cc{a} = 4; $cc{b} = 5; $cc{c} = 6; となっているわけですね。 で、この場合、$cc{a}、$cc{b}、$cc{c} には、 それぞれ $aa{a}、$aa{b}、$aa{c} と $bb{a}、$bb{b}、$bb{c} の 合計が入って欲しいわけだから、 %cc = (a => $aa{a}+$bb{a}, b => $aa{b}+$bb{b}, c => $aa{c}+$bb{c}); とするか、 foreach (a..c) { # $_ が a から c までくりかえし実行 $cc{$_} = $aa{$_} + $bb{$_}; } とするか、%aa、%bb にどんなキーが入っていてもいいことにするには foreach (keys %aa) { # $_ に %aa のキーを次々に入れながら繰り返し実行★ $cc{$_} = $aa{$_} + $bb{$_}; } とするか、 %cc = map {$_ => $aa{$_} + $bb{$_} } keys(%aa); とするか。 ★がついたのが一番おすすめか? foreach、keys、a..c、map については適当な本を調べてください。(ひでえ、、) とりあえず foreach (a..c) { print "$_\n" } とか foreach (keys %aa) { print "$_\n" } とか、 @x = (1..5); @y = map{ $_ * 2 } @x; foreach (@x) { print "$_\n"; } とか動かしてみると面白いと思います。 #もっとあっと驚く回答があったら教えてください |
すいません 下で foreach (a..c) { と書いているのは foreach ('a'..'c') { と書かないと怒られます。(警告だけで、動作はするようです) ようは、a、b、c は変数の名前でなく文字列で、 %aa、%bb、%cc というハッシュのキーですね。 %aa というハッシュの、キーが 'a' の値にアクセスするには $aa{'a'} と書きます。ただしこの場合 a はハッシュのキーであると はっきりしているので $aa{a} と省略形で書けます。 同じハッシュでキー x の値に 550 を、キー y の値に 660 を入れるには キーと値を交互に指定するリストを使って %aa = ('x', 550, 'y', 660); と書きますが、キーと値の関係をはっきりさせるために カッコの変わりに => という記号を使えば %aa = ('x' => 550, 'y' => 660); と書けます。で、この場合は => の左側はハッシュのキーなので 省略して %aa = (x => 550, y => 660); とも書けるわけです。 でも、この '' 省略方式だと、 空白を含むキーが使えません。 %kg = ('yamada tarou' => 80, 'satou tamao' => 50); だと $kg{'yamada tarou'} に 80 が、$kg{'satou tamao'} に 50 が 入りますが、 %kg = (yamada tarou => 80, satou tamao => 50); だとエラーが出て動きません。 $kg{yamada tarou} も怒られて動きません。 下のプログラムで a, b, c というのは、 ハッシュのキーで「文字列」であることを覚えておいてください。 |
ふくしさん、 こんにちわ map の使い方はまだ理解できませんが ★のコードは理解できました。 ありがとうございました。 |
はじめまして。 2日前から調べているのですが、解決できずにここにたどり着きました。 CGIからCGIへデータを渡す際に print "Location: test.cgi?data=1\n\n"; ではなくPOSTでデータを渡したいのですが Socketを使うというのを発見し、いろいろ試したのですが まるで駄目です。(Socket自体、今まで使用したことも無いので(^^;) 具体的には送信元のCGIをindex.cgi、受信するCGIをtest.cgiとしますと index.cgiに下記のような記述をしてみたのですが test.cgiには何を書いてよいのかすら分かりません。 ご教授頂けないでしょうか よろしくお願いします。 ================================ #!/usr/local/bin/perl use Socket; $server='www.*****.com'; $port = 80; $port = getservbyname($port,'tcp') unless $port =~ /^\d+/; $iaddr = inet_aton($server) or die "$serverは存在しないホストです。\n"; $sock_addr = pack_sockaddr_in($port,$iaddr); socket(SOCKET,PF_INET,SOCK_STREAM,0) or die "ソケットを生成できません。\n"; connect(SOCKET,$sock_addr) or die "$serverのポート$portに接続できません。\n"; select(SOCKET); $|=1; select(STDOUT); $file='test.cgi'; $query='data=1'; $len=length($query); print SOCKET "POST $file HTTP/1.0\r\n"; print SOCKET "Content-Length: $len" . "\r\n\r\n"; print SOCKET "$query"; ================================ |
こんな感じでは? if ($ENV{'REQUEST_METHOD'} eq "POST"){ read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'}); } @pairs = split(/&/, $buffer); foreach $pair(@pairs){ ($name, $value) = split(/=/, $pair); $value =~ tr/+/ /; $value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg; $FORM{$name} = $value; } $data = $FORM{'data'}; って、よくある掲示板のパターンですけど。(はずしてたらごめんなさい) というより、index.cgi は普通にフォームを使うだけでことは足りないのでしょうか? (Socket を使わずに) |
補足・その他です(^^; main.cgi→index.cgi→test.cgi となっていて main.cgiでフォームを使いindex.cgiにpostでデータを送信しています。 この受け取ったデータをtest.cgiにそのまま渡したいのですが、 その方法で悩んでいます。 test.cgiはメンバー入り口で受け取った会員ナンバーによって それぞれのページデータを読み込み表示するスクリプトになっていますので 直接 http://***.com/test.cgi?ID などとされて入室されるのは避けたいのです さらに考えた結果、index.cgiとtest.cgiをまとめてしまえば良い事に気付きました(^^; ですが、今後の為にもSocketを使えるようになりたいので もうちょっと努力してみます。 iwtaさんありがとうございます。 受け側では標準入力で良いのですね。 <SOCKET>をいろいろいじってみたりしてました。。。 ということは受けるほうでは use Socket; は不要なのでしょうか Socketの文献をいろいろ読んだのですが、POSTについての情報がどこも少なく (英文は読んでませんが) いろいろとお尋ねしてお手数をおかけします。 |
>>2232 名無しさん ご指摘ありがとうございます。どうやってわかりやすく説明するかは 非常に悩むところですね。autoflush は「存在自体あまり知られてない」 という痛い欠点があり、難しいところです。次回更新時に何かしら わかりやすい解説を書きたいと思っています。 >>2235 H-Hash > このたび、RFC2616の日本語訳のURLが > http://www.studyinghttp.net/rfc_ja/2616/ に変更いたしました。 ご連絡ありがとうございます。修正いたしました。 >>2236 Ka23 > UNIX プログラミング FAQのサイトが > http://www.adl.rd.nacsis.ac.jp/~moro/unix-programmer/faq-j_toc.html > に移転しているようです。 こちらもありがとうございます。後ほど修正しておきます。 >>2243 sio test.cgi は同じサーバにあるのですか? で、ブラウザから直接呼び出すこと はないのですか? ならば CGI じゃなくてただのスクリプトですので、 main.cgi からは open(IN, "/foo/bar/test.cgi ID |"); と呼び出せばいいでしょう。ソケットを使う必要はありません。 もし test.cgi が同じサーバにあって、これまでは CGI として動いていたけ ど、これからはブラウザから直接参照させたくない、ということならば、 $ENV{REQUEST_METHOD}='GET'; $ENV{QUERY_STRING}='data=1'; open(IN, "/foo/bar/test.cgi |"); と、WWW サーバの代わりに適切な環境変数をセットしてからスクリプトを実行 してやればよいでしょう。 test.cgi が別サーバにあるならば、直接スクリプトを実行することはできな いので、そのときはソケットを使いましょう。 > print SOCKET "POST $file HTTP/1.0\r\n"; > print SOCKET "Content-Length: $len" . "\r\n\r\n"; > print SOCKET "$query"; 送ったはいいけど、これでは結果を受け取っていませんし、ブラウザに何も表 示していません。 while (<SOCKET>){ # ヘッダを捨てる m/^\r\n$/ and last; } print "Content-type: text/html\n\n"; while (<SOCKET>){ # ボディのみ表示 print $_; } とかいうのをこの後に付けて下さい。 > POSTについての情報がどこも少なく あまり書くことがないからでしょう。気を付けるのはContent-length を付け ること、くらいじゃないでしょうか。 あと、CGI 経由で HTTP クライアントを開発するのはやめましょう。まずはコ マンドラインから動くような HTTP クライアントを作り、完成したら CGI 経 由でも動くように改造しましょう。でないと、問題の切り分けが非常に面倒に なります。 |
68userさんありがとうございます。 やりたい事が全てご指摘通りです(^^; open関数のパイプの使い方すら知りませんでした。 今やっと説明されているページを見つけ http://www.kt.rim.or.jp/~kbk/perl5.005/perlipc.html 勉強中です。 Socketについてもようやく理解できました。 データを受け取った側で、ブラウザ処理をしようとするから 訳が分からなくなっていたようです。 今日はperlに浸かり勉強する日にします p(..) |
X Window Systemを立ち上げるときに、 (**) stands for supplied (--) stands for probed/default values (**) ... (**) ... というメッセ-ジが出て立ち上げることができません。 これはいったいどういうことなのでしょうか。 |
正確には (**) stands for supplied, (--) stands for probed/default values (**) ... (**) ... でした。 |
>>2247 sio > データを受け取った側で、ブラウザ処理をしようとするから > 訳が分からなくなっていたようです。 まず、全体の構成を見直すべきでしょうね。 - main.cgi に統合する。 - test.cgi はユーザ名を引数で受け取り、ログイン可能なら 戻り値 0 を、ログイン不可なら戻り値 1 を返す。 などと現在の仕様を比べ、一番良さそうなものを採用しましょう。 >>2249 初心者 > (**) stands for supplied, (--) stands for probed/default values それは起動時に (成功・失敗にかかわらず) 必ず表示されるメッセージです。 また、OS などの環境が何も書いていないので、答えられる人は いないでしょう。 # 僕は XFree86 やらビデオカードやらには詳しくないので、 # 書いてもらっても答えられないかもしれませんが。 |
こんにちは。いつもお世話になってます。 Perlについて質問があります。 各ファイルに ”ー1”と ”ー2”が含まれた行があって、それを区切りに2つのファイルに分けたいのですが、なかなかうまくいきません。 EXAMPLE: *File0001の内容ーー 0001ー1 C100 Open C101 NG 0001ー2 C102 Open C103 Open *File2の内容ーー 0002ー1 C200 Open C201 NG C202 Open 0002ー2 C203 Open C204 NG この0001と0002の2つのファイルを0001ー1と0001ー2、0002ー1と0002ー2の4つのファイルに分けたいのです。 下のスクリプトは全然間違ってるのですが、/-1/ と /-2/ があった行数を記憶して、後から 行の番号を比較してどうにか区切ろうと思ったのですが、やっぱり最初は$barcode22=0だし、全然駄目です。 普通、どのようにするのか教えて頂けませんか? よろしくお願いします。 sub read_file_to_array { my($file)=$filename; open (FILE, "<$dir\\$database\\Defect\\$file") or die "Can't open $file\n"; $line=0; while (<FILE>){ if ($_ =~ /-1/) {$barcode11=$.}; if ($_ =~ /-2/) {$barcode22=$.}; if ($line > $barcode22) {print "$_ ";}#試しにSTDOU#に出力してみるだけ } $line++; } |
動くかわからんけどとりあえずできた sub read_file_to_array { #←? my $file = shift; open (FILE, "<$dir\\$database\\Defect\\$file") or die "Can't open $file\n"; open (OUT1, ">$dir\\$database\\Defect\\${file}_1") or die; open (OUT2, ">$dir\\$database\\Defect\\${file}_2") or die; my ($flag1, $flag2); while (<FILE>) { if ( /-1/ ) { $flag1 = 1; } if ( /-2/ ) { $flag2 = 1; $flag1 = 0; } if ($flag2) { print OUT2; next; } if ($flag1) { print OUT1; next; } } } |
うぎょぎょ。。if ($flag2) {〜の部分の順番が逆になっちゃってるし。ダサ・・ closeしてないし・・終了時に閉じられるから大丈夫かアハハ |
>>2251 ミング 必ずデータの先頭が .*-1 か .*-2 であるなら while (<FILE>) { if ( /-[12]/ ){ chomp; open (OUT, ">$dir\\$database\\Defect\\$_") or die; next; } print OUT; } かなぁと思うんですが、違うかな? 業務用プログラムかだとちゃんとエラーチェックしないとまずい でしょうが、データの内容がある程度保証されているなら、こんな テキトーな感じでよろしいかと思います。 |
ナナシサソさん、68userさん 出来ました!! ご指導どうもありがとうございました。 |
二日連続の質問になってしまいますが、よろしくお願いします。 No.2251のInput file名は"Ab00010", "Cd00020", のように文字と数字からなっているのですが、Outputは別のDirに"Ab00010" "Ab00011" "Cd00020" "Cd00021"というように、/-2/の部分は”元のファイル名+1”というファイル名にしたいのですが、、、、 800ページあるらくだの本も一応買ってきたのですが全然分からないので、ウェブサイトで調べてみたのですが、唯一これかな?と思ったのが: $string="abcd771gfds"; $string=~/(\W+)\s+(\d+)/; とすると、$1=abcd, $2=7771, $string=abcd771gfds になる、とあったんですが、 試してみると$1=" ", $2=" ", $string="4294967295"になってしまい、訳が分からなくなってきたのですが、これは全然違うアプローチなんでしょうか? どうしたら ”Ab00011”が作れるんでしょうか? |
$flag == 2 ? $string ++ : ; でいいと思う・・ゲロゲロ |
UNIXの歴史について、知ってる範囲で教えてください。 できれば、メールの方がありがたいです。 |
>>2257 ナナシサソ でもアルファベットと数字からなってるので、数字だと見てくれないみたいなんですけど、、、 |
>>2259 ミング Perlは妙なことが出来たり・・ 多分うまくいくと思うんだけどな・・ |
ミングさんはじめまして。 まず abcd771gfds の件です。 #!/usr/bin/perl $string = "abcd771gfds"; $string =~ /(\W+)\s+(\d+)/; print "1:<$1> 2:<$2> string:<$string>\n"; を動かすと 1:<> 2:<> string:<abcd771gfds> と出ました。 \W+ は、英数字(word)以外1文字以上なので、なくてあたりまえ。 \s+ は、空白文字(space)1文字以上なので、なくてあたりまえ。 \d+ は、数字(digit)1文字以上だが、前に \W も \s もないのでダメ。 もし、$1 に abcd、$2 に 771(7771 は間違い?)を入れようとするなら、 $string =~ /^([a-zA-Z])(\d+)/; とかでしょうか。 ^ は文字列の先頭を示します。 これをやらないとどこからサーチしはじめるかわからん。 [a-zA-Z] は英字。\d は数字。 (わー、目からウロコ。英字のカンタンな文字クラスってないんですね) #!/usr/local/bin/perl $string = "abcd771gfds"; $string =~ /^([a-zA-Z]+)(\d+)/; print "1:<$1> 2:<$2> string:<$string>\n"; を動かすと 1:<abcd> 2:<771> string:<abcd771gfds> となりました。 |
ミングさん、つぎにファイル名生成の件です。 もっとカッコいいプログラムはいくらでもあるかと思うんですが、 ここではわかりやすく確実に動くのを取りました。 #!/usr/bin/perl $fname = "Ab00010"; $fname =~ /([a-zA-Z]+)(\d+)/; $fname_a = $1; # 英字部分 $fname_n = $2; # 数字部分 $fname_n++; # 数字部分に1加算 $fname_n = sprintf "%05d", $fname_n; # 先頭にゼロを詰めて5文字に $fname = $fname_a.$fname_n; print "fname: $fname\n"; $fname_n++; # 数字部分に1加算 $fname_n = sprintf "%05d", $fname_n; # 先頭にゼロを詰めて5文字に $fname = $fname_a.$fname_n; print "fname: $fname\n"; $fname_n++; # 数字部分に1加算 $fname_n = sprintf "%05d", $fname_n; # 先頭にゼロを詰めて5文字に $fname = $fname_a.$fname_n; print "fname: $fname\n"; 実行してみます。 fname: Ab00011 fname: Ab00012 fname: Ab00013 ポイントは sprintf でしょうか。 これは文字列をいろんな形で整形しますが、汎用性が高すぎるので、 sprintf "%0n", m; n はケタ数、m は数字 で、m を n ケタ、ゼロ詰めで表示するとだけ今はご説明します。 ただですね、これだと1ファイルが10個以上のサブファイルに分けると Ab0002n に突入してしまって、 もし Ab00020 という元ファイルがあると名前が衝突しますが、 それはいいですか。 |
>>2258 オハツ > UNIXの歴史について、知ってる範囲で教えてください。 「UNIXの1/4世紀」 http://www.ascii.co.jp/books/detail/4-7561/4-7561-3659-1.html を読みましょう。 |
ふくしさん、ナナシサソさん、 ご教授どうもありがとうがざいました。 やっと出来ました。 とても分かり易く助かりました。 今後もいろいろと宜しくお願いいたします! |
はじめまして。教えていただきたいことがあります。 こちらを参考に、perlのネットワークプログラムを作りたいと思っています。OSはPlamo Linux、perlは5.005です。 やりたいのはローカルネットワーク上に、ブロードキャストでメッセージを送って、ポートを開いている全部のコンピュータがそのメッセージを受信するというものです。 試験として #!/usr/local/bin/perl use IO::Socket; $socket = IO::Socket::INET->new( PeerAddr => '192.168.0.255', PeerPort => 2425, Proto => 'udp', ); if ( ! $socket ){ die "接続できませんでした。 $!\n"; } print $socket "test"; $socket->flush(); $socket->close(); と、いうのを動かしてみました。ブロードキャストである192.168.0.255ですから、2425でポートを開いている他のPC(VBのwinsockを使いました)にtestが表示されるかと思ったのですが、 > 接続できませんでした。 不正なファイルデスクリプタです というエラーが返って来てしまいます。 このエラー、192.268.0.3の様にIPを指定すると、出現しません。 いろいろとサーチエンジンなどもあたったのですが、どうしてもこの原因がつかめず、困っています。 perlを使って、udpとブロードキャストアドレスでネットワーク通信されている方がいらしたら、ブロードキャストアドレスをどうやって指定しているか、教えていただけませんでしょうか? よろしくお願いいたします。 |
>>2265 武田一浩 broadcast するときは、socket option の設定 $socket->setsockopt(SOL_SOCKET, SO_BROADCAST, 1) || die "$!"; が必要です。 IO::Socket じゃなくて普通の Socket モジュールを使うなら setsockopt($socket, SOL_SOCKET, SO_BROADCAST, 1) || die "$!"; ですね (これは IO::Socket で生成したソケットに対しても有効です)。 ただ、こちらで試した限りでは、 > 接続できませんでした。 不正なファイルデスクリプタです というエラーは出ませんでした。if ( ! $socket ) でエラー になっているということは、何か別の原因があるような気がします。 ちなみに printf $socket "1:%d:name:hostname:%d:ext\0group", time(), 0x1; で参加通知です。 |
No. 2266 # 68user さん、リプライありがとうございます。 次の様に修正してみました。 #!/usr/local/bin/perl use IO::Socket; $socket = IO::Socket::INET->new( PeerAddr => '192.168.0.255', PeerPort => 2425, Proto => 'udp', ); $socket->setsockopt(SOL_SOCKET, SO_BROADCAST, 1) || die "$!"; if ( ! $socket ){ die "接続できませんでした。 $!\n"; } printf $socket "test"; $socket->close(); 結果は、 Can't call method "setsockopt" on an undefined value at ./udptest.pl line 11. でやはり駄目でした。 192.168.0.255のアドレスを、特定のPCのIPに設定すると、そのPCにはtestの表示が出ますから、スクリプトそのものにはエラーがないのだと思いますが、なぜか私の環境ではブロードキャストアドレスが使用できない(?)のではないかと思います。 とりあえず、Perlやスクリプトには異常がなさそうなので、Plamo Linux のMLにでも質問をあげてみることにします。 ありがとうございました。 |
・・ <% strPathName = "HTTP://××/××/××/○○○.xls %> <a href=<% =strPathName%> ><% = strData(cnt)(0)%></a> ・・ </html> 上記のようにリンクしたいパス名を設定しました。 やりたいことは、 既存のダイアログ『ファイルのダウンロード画面 次の場所からファイルをダウンロードするように選択しました』 を表示させてからExcelを表示したいのですがどうしたらいいですか? 現象として、 すぐにExcelが表示されてしまいます。 |
はじめまして、どうしても分からない事があるので質問させて下さい。 HTMLの中にSSIでCGIのファイルを読み込ませようとしたのですが <!--#include file="test.cgi" --> だとOKなのですが <!--#include file="test.cgi?id=kouji" --> のように引数を付けると [an error occurred while processing this directive] とエラーになってしまいます。 「?」の部分からエラーが表示されるのですが、これを回避する方法を教えて下さい。 webも調べてみたのですが、結局分かりませんでした。 http://tohoho.wakusei.ne.jp/wwwssi.htm こちらの下の方に書いてあるexecの例で >○ <!--#exec cgi="xx.cgi"--> >× <!--#exec cgi="xx.cgi arg1 arg2"--> >× <!--#exec cgi="xx.cgi?arg1+arg2"--> >× <!--#exec cmd="xxx.pl"--> >○ <!--#exec cmd="/bin/xxx arg1 arg2"--> >○ <!--#exec cmd="./xxx.pl arg1 arg2"--> これの○で書いてあることみたいに引数を渡そうとしても駄目でした・・・ よろしくおねがいします。 |
なんでも聞いてすいません。 Windows 2000 以降についてくる「メモ帳」の「名前をつけて保存」では、 ISO-2022-jp および Shift_JIS(正確には Windows 932 および Windows 1152)のことを 「ANSI」と呼び習わしていますが、これはどういう経緯でしょうか? ANSI といえばアメリカの工業規格で、ASCII や ISO-8859-1 を規定してるもんだと 思い込んで生きてきましたが、Delphi の入門本とか ML とかを見ても 「ANSI 文字列を Unicode に変換、、」とかいって、 Windows で使える Unicode 以外の文字、という意味で ANSI 文字列、 と書いてあるようなんですが、この言葉は正しい業界用語なんでしょうか? それとも Windows ローカル語? この言葉のスコープはどこまでなんでしょうか? 「メモ帳」といえば UTF-16LE-BOM のことを「Unicode」、 UTF-16BE-BOM のことを「Unicode Big Endian」、UTF-8 のことを「UTF-8」と言ってますが、 これなんかも業界用語なのか Windows 語なのか単なるメモ帳の開発者の気の迷いなのか わかりません。(あ、でも Word も共通なんだよな、、) 場違いでしたら情報のポインタや、討議するのにふさわしい掲示板等教えてください。 よろしくお願いいたします。 |
とても素人で、申し訳ないのですが、ご存知の方がいらしたら、教えて下さい。ハードは、IBM社のRS/6000を使用しています。kシェルを作成して下記の作業を行いたいと考えています。 複数のテ゛ィレクトリーに10〜30のファイルが存在しています。 各ファイル中に/usr/kokyakuと記述があれば、/usr/okyaku と変更したいと考えています。sedコマンドを利用すればそれぞれのファイルの中身を変更させることは可能であることは、分かったのですが、対象の ファイル数が多い為、該当のディレクトリーにcdし、 grep -l'/usr/kokyaku' * > filename などで、対象ファイル名を保存したファイルを作成し、そのファイルを自動的に読み込んでファイル名をいちいち指定せずにsedコマンドを実行でき ないものでしょうか?awkコマンドでファイル名が保存されているファイルを読み込み、sedコマンドの出力ファイルを$1の名前にするなどは可能なのでしょうか? ちなみに、イメーシ゛的には、カレントディレクトリーの下のファイル(*)の内容を自動的に置換してほしいのですが… sed 's/\/usr\/kokyaku/\/usr\/okyaku/g' * >*の出力 つたない説明で、申し訳ありませんが、お知恵を頂けたらありがたいです。 |
みーさん: Perl ですいません、一応テストもしました。 ミソは find コマンドの出力を ` ` で配列に入れて for で処理している、、(フツーやんねえかな、、) #! /usr/local/bin/perl -w # kokyakuokyaku $tmp = "TempFileDayooon"; # 中間ファイル。存在しないファイル名を選ぶこと for $file (`find . -print`) { chomp; if (-f $file) { open FILE, $file; open TMP, ">$tmp"; while (<FILE>) { s|/srv/kokyaku/|/srv/okyaku/|g; print TMP; } close TMP; close FILE; rename $tmp, $file; } } |
(一応)ふつー File::Find 使うよね。知ってるー (^^;;; |
ふくしさんどーもありがとうございました。大変申し訳ないのですが、findコマンドの使い方をよく理解していないので、どなたかお教え頂けないでしょうか?私の理解としては、ディレクトリー内の条件にあったファイルを探す時に使うコマンドだと思っていたので、例えば、頭に’m*’がつくファイルを探したりする時に使用するものだと思っていました。1つあるいは複数のファイルから、指定パターンに合致した行を探しその対象のファイル名を表示させる為には、grepしか使用出来ないと思っていたのですが、findコマンドで、ファイル(シェル)中に/usr/kokyakuと記述されているファイル名をfindコマンドで探す場合は、どのように記述すればよいのでしょうか? また、ふくしさんの記述して下さった各行の処理内容をもう少し詳細に教えて頂けないでしょうか?お手数をおかけいたしますが、よろしくお願いいたします。 |
>>2267 武田 一浩 $socket = IO::Socket::INET->new( PeerAddr => '192.168.0.255', PeerPort => 2425, Proto => 'udp', ) || die "$!"; とした方が、どこでエラーが出ているかを把握しやすいでしょう。 > とりあえず、Perlやスクリプトには異常がなさそうなので、 そうですね。perl か OS の問題ではないかと思います。 あと、ifconfig -a して、デバイスに fxp0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> mtu 1500 と、「BROADCAST」が付いていてブロードキャストに対応していることを 確認して下さい。もしかして ppp デバイスだったりすると付いてないかも。 >>2268 もみの木 > 現象として、すぐにExcelが表示されてしまいます。 要は、ASP は全く関係なくて <a href="HTTP://××/××/××/○○○.xls">hoge</a> というリンクをクリックしたときの挙動ですよね? Windows は よくわからないので、 http://www.parkcity.ne.jp/~chaichan/bin/qanda.cgi?modefg=9 で質問した方がよろしいと思います。 あとの話題は後ほど。 |
みーさん: なんかすいません。 たぶんぼくのやり方すごく非標準的なので、 もっとカッコいい方法はいくらでもあると思うんですが、、 find はファイル名の検索、 grep はファイルの中の文字列の検索、 で、合ってます。 ぼくのスクリプトでは各ファイルの中での文字列検索/置換を 自分で書いています。(while のあたり) #! /usr/local/bin/perl -w # kokyakuokyaku $tmp = "TempFileDayooon"; # 中間ファイル。存在しないファイル名を選ぶこと for $file (`find . -print`) { chomp $file; # すいません、ココ、間違ってました if (-f $file) { open FILE, $file; open TMP, ">$tmp"; while (<FILE>) { s|/srv/kokyaku/|/srv/okyaku/|g; print TMP; } close TMP; close FILE; rename $tmp, $file; } } `UNIXコマンド` …バッククォート(`)でUNIXのコマンドを囲むと、 出力結果をリストで返す for $変数 (リスト) { ...なんだかんだ... } …リストの要素を1個ずつ $変数 に入れながら、 「なんだかんだ」の部分を繰り返す。 上では find の結果を1行ずつ $file に入れて処理している。 それはカレント ディレクトリ以降のファイル/ディレクトリである。 % find . -print …カレント ディレクトリ以降のファイル/ディレクトリを一覧表示する。 chomp $file; …$file(find の結果の1行)の末尾から改行を取り除いて、 ファイル/ディレクトリ名として正しいものにしている -f 文字列 …「-f」はファイルテスト演算子のひとつ。 右に来る文字列がふつうのファイルだったら真を返す。 ここではディレクトリをはじいている。 open FILE, $file; …ファイル名 $file のファイルを入力で開いて、 ファイルハンドル FILE で入力アクセスできるようにする open TMP, ">$tmp"; …ファイル名 $tmp のファイルを出力で開いて、 ファイルハンドル TMP で出力アクセスできるようにする while (<FILE>) { ...なんだかんだ... } …ファイルハンドル FILE で読み込まれる ファイル $file(ここでは find の結果のうち、ファイルのみ)の 1行1行を、$_ という特殊な変数に入れながら 「なんだかんだ」の部分を繰り返す。 $file を読み終わったらループを脱出する s|/srv/kokyaku/|/srv/okyaku/|g; …デフォルトの作用対象である変数 $_ に対して、 「/srv/kokyaku/」を「/srv/okyaku/」に置換する。 s は substitute(置換)、g は global(全体的に)の略。 g を略すと1行に1回しか置換しない print TMP; …TMP ファイルハンドルに、デフォルトの作用対象 $_ を出力する ここで $_ は FILE の1行1行に 「/srv/kokyaku/」=>「/srv/okyaku/」の置換を施したものである close TMP; close FILE; …ファイルを「閉じる」。 (ファイルアクセスのために確保されていたメモリなどの資源を解放する) rename $tmp, $file; …置換する前のファイル名が $file、 置換したあとのファイル名が $tmp なので、 $tmp を $file に改名する。 これで置換したファイルで元ファイルは上書きされ、 中間ファイル TempFileDayooon は消えてなくなる こんな感じでしょうか。 |
>>2271 初心者みーです。 複数ファイルの中身を一括置換する、という目的に限れば、 http://x68000.startshop.co.jp/~68user/unix/pickup?perl の perl -pi.bak -e .. ところをどうぞ。 > findコマンドで、ファイル(シェル)中に/usr/kokyakuと > 記述されているファイル名をfindコマンドで探す場合は、 > どのように記述すればよいのでしょうか? いろいろありますが、以下のような感じです。 % find . -exec grep -l /usr/kokyaku {} \; … 機能は実現できるけど、遅い。 % grep -l * … ファイル数が多すぎるとダメ。ファイル数が数千程度ならこれでいいでしょう。 % find . -print | xargs grep -l … ファイル数が多くても OK。 % find . -print0 | xargs -0 grep -l … ファイル数が多くても OK。ファイル名に改行が含まれていても OK。 今回は grep -l でいいのではないでしょうか。 あと、 > sed 's/\/usr\/kokyaku/\/usr\/okyaku/g' * >*の出力 で実現できることはわかっているので、後はこれを複数のファイルに対して実 行すればよいのです。いろいろ方法はありますが、お勧めなのは「文字列をい じくってコマンドラインを作り、sh に喰わせる」方法です。 grep -l * で、 file1 file2 file3 という出力が得られるとします。次に grep -l * | sed "s|\(.*\)|sed 's./usr/kokyaku./usr/okyaku/.g' < \1 > out/\1 | " とすると、 sed 's./usr/kokyaku./usr/okyaku/.g' < ./file1 > out/./file1 sed 's./usr/kokyaku./usr/okyaku/.g' < ./file2 > out/./file2 sed 's./usr/kokyaku./usr/okyaku/.g' < ./file3 > out/./file3 という文字列が得られます。それをよく確認して、よさそうなら grep -l * | sed "s|\(.*\)|sed 's./usr/kokyaku./usr/okyaku/.g' < \1 > out/\1 | " | sh と末尾に | sh を付ければ、そのまま実行されます。 正しいコマンドラインができるまでは「| sh」を付けずに試行錯誤すれば よいので、いろいろなところで応用が効くと思います。 |
>>2270 ふくし > 場違いでしたら情報のポインタや、討議するのにふさわしい > 掲示板等教えてください。 場違いではないですが、わかりません。会社では Windows Me だし (笑) ふさわしいところは… fj.kanji くらいしか思い付かないなぁ…。 後は >>2269 kouji ですが、これはちょっと調べてから回答したいと思います。 |
ふくしさん、68userさんどうもいろいろありがとうございました。とっても勉強になりましたし、助かりました。perl -pi.bakの方法で、一括変換変換させる方法をバックアップファイルも一緒に作成できるので、実施したいと思います。簡単なテストをしたところ、大丈夫そうでしたので…。他の方法も、今後時間のある時に試してみたいと思います。迅速なご回答と親切な説明、本当にありがとうございました。 |
始めましてm(__)m UNIXを学校で使っています。 家では使えないんでしょうか? 家にパソコンはあるのですが…(-.-;) |
ぷたろさん、はじめまして。 ・家のパソコンに UNIX(FreeBSD とか Linux)を入れる。 いろんな本に、すでに入ってる OS(Windows ですか?)と切り替える方法が 書いてある<=管理が大変だけど ・家のパソコンをインターネットにつなぎ、 会社のパソコンに Telnet(Windows だと Teraterm が有名)で ログインする。リモートコントロールの感覚ですね。 グラフィックなソフトは使えないけど、、。 この場合は学校の管理者の人に聞いてみてください。 |
ふくしさん、ありがとですm(_ _)m 家のパソコンのOSはwindowsです。 外付けのハードを買って そこにLinuxを・・・。 ってな具合にはいかないですか? う〜ん、どうしよう(--;) |
>ぷたろさん いちから Linux を入れて自分で管理する気があるんだったら、可能ですよ。 いまの Windows の HDD に余裕があるんだったら、 同じ HDD にパーティションを切って入れてもいいし、 新しい HDD を買う予定があるんだったら、ぷたろさんがおっしゃるように 外付けのでも新しい内蔵のでも入れて、そこに入れてもいいし。 要するに、今使ってる Windows のマシンに新しく Linux を入れて、 Linux と Windows と切り替えて使うことは可能です。 体験するだけだったら、ここの会社 http://www.mlb.co.jp/ のが 面白そうです。Live Linux というのは Windows マシンに CD-ROM を 突っ込むと Linux 体験が出来るそうです。あと MLD5 というのは Windows のパーティションを壊さずに(フォーマットせずに)そのまま Linux を入れられ、Linux は Windows からハードウェアの設定を 読みこんで自動インストールしてくれるそうです。 ぼくはどっちも使ったことないし、設定は人に任せているのでくわしいことは わからないのですが、トライしてみたらどうでしょうか。 |
ふくしさん、親切にありがとうございますm(_ _)m 同じHDDにいれるんだったら HDDを分割するソフトがないと ダメですよね? HDDを新しく買って Linuxを一からやってみようかな。。。 Linuxを自分で管理って大変なんですか? 「いちから Linux を入れて自分で管理する気があるんだったら」 ってあるから大変そう・・・。 う〜ん。新しい事をするのは難しいです(-.-;) |
>ぷたろさん HDDにパーティションを切るソフトは、商用のLinuxにはたいてい ついてきます。少なくともMLD5にはついてきます。 あと、FIPSというフリーのパーティションソフトもあります。 新しいHDDを買ってきてもいいですが、 どのディスクからブートするかを指定する何らかの手段が必要です。 この掲示板だけではフォローしきれないと思うので(^^; 適当な入門用Linuxを買ってみるといろいろ書いてあると思います。 それから大変かどうかですが、それは人によります。 最近の入門用のディストリビューションは 最初からなんでも使えるようになっているようですが、 もしネットワークにつなぎっぱなしにする環境なら、 不要なサービスを殺さないと外からどんどん入ってこられます。 最低でも root(管理者用ユーザー)のパスワードは設定してください。 では、がんばってくださいー。 |
たびたび申し訳ありません。また、教えて下さい。perlのコマンドでカレンドディレクトリの中の複数ファイルを対象に、該当の文字(/usr/kokyaku)を特定の文字(usr/okyaku)に置換させようと考えています。下記のコマンドを実施したところ、特定文字を含まないファイルについても、バックアップファイル**.bakが作成されてしまいます。該当のファイルのみバックアップファイルを作成することは可能でしょうか? perl -pi.bak -e 's/\/usr\/kokyaku/\/usr\/okyaku/g' * カレントディレクトリーには、20ほどのファイル(ほとんどがシャル)が存在し、上記文字を含むファイルが6つほど存在するので、6つのみファイルの中身を置換し、バックアップファイルも6つのみ作成してほしいのですが、わがままなお願いでしょうか?お手数をおかけいたしますが、簡単な方法があれば教えて下さい。 |
>>2286 みー > バックアップファイル**.bakが作成されてしまいます。 おそらくそういう仕様です。 で、どうすればいいと思いますか? 不要なファイルができて困るのなら、不要なファイルを作らないように するか、不要なファイルを削除すればいいわけで。 まずは自分で考えてみて下さい。 |
今晩は、初めまして。 突然ですが質問して宜しいでしょうか。 ホスト名と、IPアドレスの頁を読ませていただいたのですが、まだ良く分かっていないので、この場をお借りして質問させていただきます。 IPアドレスが微妙に違って、でもホスト名が同一の場合、それは同一のパソコンからアクセスしていると解釈していいのでしょうか? すみません、物知らずで…教えてくださると嬉しいです。 |
68userさん、回答ありがとうございました。仕様でそうなっているのでは、仕方がないので諦めて、カレトディレクトリーに該当ファイル数が少ない場合はファイルを指定し、該当ファイル数が多い場合は、不要なファイルを後で、rmで削除することにします。 |
>みーさん えーシェルスクリプトも Perl もつかえる環境なのに手動でやるんですか、 それはもったいない、、失敗もしそうだし、、 >TAKEさん 相手がプロバイダーの場合など、同じホスト名でも ちがうパソコンのことがあるのでは、、。 |
回答が遅くなったので、もう見ておられないかもしれませんが… >>2269 kouji exec cgi、include file には引数を渡せない、という仕様の ように思えます。ソースを読んでみたのですが、いまいち わからなかったので自信はないのですが。 ただし、include virtual なら <!--#include virtual="./a.cgi?a=b&c=d" --> というふうに書けば引数を渡せます。 どうしても include file、exec cgi で、ということなら <!--#set var="QUERY_STRING" value="hoge=1" --> <!--#include file="./a.cgi" --> <!--#exec cgi="./a.cgi" --> などとやってみたのですが、QUERY_STRING の値は上書き されてしまうようなので、これはダメ。よって、 <!--#set var="MY_QUERY_STRING" value="hoge=1" --> <!--#include file="./a.cgi" --> <!--#exec cgi="./a.cgi" --> などとして、CGI 側では QUERY_STRING でなく MY_QUERY_STRING を 使う、という方法しかないように思えます。 まぁそんなことをするくらいなら、素直に include virtual を 使った方がよいでしょうけれども。 |
>>2236 Ka23 > UNIX プログラミング FAQのサイトが > http://www.adl.rd.nacsis.ac.jp/~moro/unix-programmer/faq-j_toc.html > に移転しているようです。 遅くなりましたが修正いたしました。 # http://x68000.startshop.co.jp/~68user/cgi-bin/cvsweb.cgi/public_html/net/org/link-book.html が、今 www.adl.rd.nacsis.ac.jp には unreachable なので、 そのページはまだ見ていません。 |
>>2159 Nira > そういえば、httpsの取得に良いサイトを発見しました。 > https://www2.ggn.net/cgi-bin/ssl です。 http://x68000.startshop.co.jp/~68user/net/ssl.html に反映しました。 # http://x68000.startshop.co.jp/~68user/cgi-bin/cvsweb.cgi/public_html/net/org/ssl.html 他にも「前に情報提供したのにまだ反映されていない」という部分が ありましたら、ご指摘いただけると幸いです。 |
>68userさん ありがとうございました。 include virtualを使います。 |