• 締切済み

perlのプログラミングで悩んでいます

open(IN,"<data/list.cgi"); @list = <IN>; close(IN); このようなプログラムで、 'abc','def','ghi' とだけ書かれた「list.cgi」をdataディレクトリに用意しています。 そして、print "$list[0]";で読み込むと、 'abc','def','ghi' と全て表示されてしまいます。 原因がわからないので、質問しました。 お願いします。

  • Perl
  • 回答数2
  • ありがとう数1

みんなの回答

  • kmee
  • ベストアンサー率55% (1857/3366)
回答No.2

原因ははっきししています。 <>をリストのコンテキストで使用すると、ファイル全体を読み込み、行毎に分解したリストを返します。 # Perlを使う上でリストとスカラーのコンテキストは重要なものです。しっかり理解してください。 このプログラムでは @listにlist.cgiの各行を要素とするリストが入ります。 $list[0]には list.cgiの1行目になっています。 ファイルの1行目には 'abc','def','ghi' ですから、 'abc','def','ghi' になります。 ファイルには2行目以降がないので、$list[0]で全部であり、$linst[1]以降には何も入っていません。 以上のように、まったく仕様通りの動作です。なんの不思議もありません。 原因は、「違う動作を期待する、あなたの不理解」です。 カンマで分解したいのでは、と推測されますが、それなら、次のような方法を使います。 ・split関数を使う ・入力セパレータを表わす特殊変数 $/ を $/=',' と変更して、<>が「カンマ毎に分解する」ようにする(他にも影響が大きいのであまり勧められない) list.cgiというファイル名からすると、 ファイルの内容をPerlでの記述と解釈させようとしているのではないか、とも推測されます。 @list=('abc','def','ghi'); と書いたのと同じ状態にしたかったのでしょうか。 <>にそんな機能はありません。 他のファイルに書かれたPerlスクリプトを利用するには、次の方法があります。 ・require を使う ・モジュールにしてuseを使う ・<>で文字列として取り込んで evalで解釈する 単にリストの内容を別ファイルに記述しただけなら、その別ファイルをPerlスクリプトとして書く必要はありません。 ・<>で取り込んで必要に応じて文字列操作する

noname#140270
noname#140270
回答No.1

split はいかがですか? その場合は、' ' でくくる必要はないのかもしれません。 open(IN,"<data/list.cgi"); @list = split( /,/, <IN>); close(IN); print "$list[0]"; 'abc' となると思います。

関連するQ&A

  • Perlのキャプチャ

    プログラム #!/usr/bin/perl my $str = "abc,def,ghi"; ($a,$b,$c) = $str =~ /(.*),(.*),(.*)/; print $a,"\n"; print $b,"\n"; print $c,"\n"; 実行結果 abc def ghi このようなプログラムで ($a,$b,$c) = $str =~ /(.*),(.*),(.*)/;は それぞれ$a,$b,$cにabc,def,ghiが入ります. キャプチャしたすべてを変数に入れるならこの方法ですが, defだけが欲しいのに変数を3つ用意する必要がないと思います. 間違った表記ですが, ($b) = $str =~ /(.*),(.*),(.*)/$2/; 2つ目にキャプチャした$2が変数$bに入るような表記は出来ないのでしょうか?

  • dataファイルの特定の行から特定の行をダンプさせるには?

    $ cat data.txt #No1. abc... #No2. def... #No3. ghi... #No4. jkl... #No5. mno... なるデータの、例えば#No2.から#No4.までのデータだけをダンプするのに、 open(IN,"data.txt"); my $flag=0; while(<IN>){ if ( $_ =~ /#No2./ && $flag == 0) { $flag=1; } if ( $_ =~ /#No5./ && $flag == 1) { $flag=0; } print if $flag==1; } close(IN) と書いてみましたが、もっと簡単に書く方法を以前見たことがあったように思うのですが、こう書けばよいのでは?というアイディアがあれば、ご教授いただけないでしょうか?

    • ベストアンサー
    • Perl
  • Perlの文字列置換について

    質問です。文字列の置換を行いたいのですが、まずはソースから・・・ use File::Basename; use File::Copy; use File::Find; use File::Path; my @filelist = (); $inputfile='C:\Users\test.txt'; $outputfile='C:\Users\test_new.txt'; open (IN, $inputfile) or die "$!"; open (OUT, ">$outputfile") or die "$!"; while(<IN>) { $str = $_; if ($str =~ /html:text/) { $str =~ s/html:text/s:textfield/g; $str =~ s/property/name/; $str =~ s/styleClass/cssClass/; elsif($str =~ /html:textarea/) { $str =~ s/html:textarea/s:textarea/g; $str =~ s/property/name/; $str =~ s/style/cssStyle/; $str =~ s/styleClass/cssClass/; } print OUT $str; } close (IN); close(OUT); sub wanted{ push(@filelist, $File::Find::dir."/$_") unless ($_ =~ /^\.$/); } Perlプログラムで下記のソースを一括置換します。 <html:text property="xxx" styleClass="yyy"> <html:textarea property="abc" styleClass="def" style="ghi"> 目標は以下のように置換したいです <s:textfield name="xxx" cssClass="yyy"> <s:textarea name="abc" cssClass="def" cssStyle="ghi"> しかし、上記のプログラムを実行すると <s:textfield name="xxx" cssClass="yyy"> <s:textfieldarea name="abc" cssClass="def" style="ghi"> となってしまいます。 どこをどう直せばよいのかわからないので誰か教えてください。 お願い致します!!

    • ベストアンサー
    • Perl
  • 二次元配列の分割

    よろしくお願いします。 $hoge = array( "one" => array("abc" => "100", "def" => "200", "ghi" => "300"), "two" => array("abc" => "110", "def" => "210", "ghi" => "310"), "three" => array("abc" => "120", "def" => "220", "ghi" => "320") "four" => array("abc" => "130", "def" => "230", "ghi" => "330") ); というような配列があったとき、 abcが110以下のときと、110より大きい場合で分割した配列を 用意したいと考えてます。 具体的には、 $hoge1 = array( "one" => array("abc" => "100", "def" => "200", "ghi" => "300"), "two" => array("abc" => "110", "def" => "210", "ghi" => "310"), ); と $hoge2 = array( "three" => array("abc" => "120", "def" => "220", "ghi" => "320") "four" => array("abc" => "130", "def" => "230", "ghi" => "330") ); に分割したいと考えています。 どのように記述すればよいのでしょうか?

    • ベストアンサー
    • PHP
  • プログラミングについて教えてください!

    rubyについてのプログラムで、テキストファイルの中に人の名前と住所が書かれていて、その人の住所が登録されていると、その人の住所が表示され、なければnilを返すプログラムを作りたいと思っていて、 def (search)から後をどう書いたらいいのかわからないので、是非教えていただきたいのでお願いします! class AddressFile def Initialize(file) @original = file @meibo = {} fo = open(file,"r") lines = fo.readlines fo.close for aLine in lines data = aLine.split @meibo[data[0]] =data[1] end end attr_accessor :meibo end def search(name) end end obj = AddressFile.new("address_list.txt") obj.search(○○○○) テキストファイルの中身は、名前、住所の順番で入っています。このプログラムでおかしいとこがあれば、それも教えていただきたいです! よろしく、お願いします!

    • ベストアンサー
    • Ruby
  • Makefileの書き方

    正しいかどうかわかりませんが、インターネットである程度検索してから以下のようなJavaのコンパイル用Makefileを作成しました。なお、全てのクラスのパッケージは package abc.def.ghi; です。 ---Makefile--- .SUFFIXES: .java .class JC = /usr/bin/javac PATH = ./abc/def/ghi/ CLASSPATH = -classpath /Users/macintosh/ TARGET1 = Prog1 TARGET2 = Prog2 TARGET3 = Prog3 list: $(PATH)$(TARGET1).class \ $(PATH)$(TARGET2).class \ $(PATH)$(TARGET3).class .java.class: $(JC) $(CLASSPATH) $< clean: /bin/rm -f $(PATH)*.class これで/Users/macintoshディレクトリからmakeを実行すると、 /usr/bin/javac -classpath /Users/macintosh/ abc/def/ghi/Prog1.java /usr/bin/javac -classpath /Users/macintosh/ abc/def/ghi/Prog2.java /usr/bin/javac -classpath /Users/macintosh/ abc/def/ghi/Prog3.java が実行され、無事にクラスファイルが3つ生成されます。-classpathによりクラスパスも同時に設定されるので、あとはどこのディレクトリからでも $java abc.def.ghi.Prog1 でプログラムが実行されると思ったのですが/Users/macintosh/以外のディレクトリから実行すると Exception in thread "main" java.lang.NoClassDefFoundError: というエラーになります。何がおかしいのでしょうか。あと、Java用のMakefileで改善したところがあれば教えて下さい。

    • ベストアンサー
    • Java
  • Perl 教えてください。

    下記のような簡単なスクリプトなんですが、なぜかサーバーにアップすると動きません。 ローカルでコマンドプロンプトから直接実行するとまともに動作します。 パーミッションは「755」と「705」でやってみましたが。 perlのパスは合っていますし、実際同じ場所に置いた他のCGIは動作します。 #!/usr/bin/perl open (DT, "<./data/***/***.csv") or die "File '***.csv' Open Error."; @data = <DT>; $data[0] = ",,,,,,\n"; open (OUT,">./data/***/***1.csv") or die "File '***1.csv' Open Error."; print OUT @data; close (DT); close (OUT); 原因が分からず困っています。 解決策でなく、原因と思えるだけの回答で結構ですので何卒よろしくお願いいたします。

    • ベストアンサー
    • Perl
  • UNIXでfindとls

    UNIXでファイルを検索するのにfindコマンドを使用してますが 情報として、パス名だけが表示されます。 >find . -name ghi -print ./ghi ./abc/def/ghi ./abc/def/ghi/ghi これを、ファイルのいろんな情報を見ることはできないでしょうか? パイプを使おうと思ったのですが、いまいちわかってなくて できませんでした。

  • Perlのプログラミングについて

    Perlのプログラミングでつまづきました。 # ファイルから指定文字列を含む行を収集する # 入力ファイルのオープンと読み込み print( "入力ファイル名?" ); $n = <STDIN>; chomp( $n ); open( FIN, "<$n" ) or die "入力ファイルオープンエラー: $!\n"; $n = @a = <FIN>; close( FIN ); print( "$n 行読み込みました\n" ); # 行の収集 print( "検索文字列?" ); $x = <STDIN>; chomp( $x ); $ptn = $x; #指定の文字列 $x = @b = grep( /$ptn/, @a ); print( "$x 行見つかりました\n" ); # 出力ファイルのオープンと書き出し print( "出力ファイル名?" ); $y = <STDIN>; chomp( $y ); open( FOUT, ">$y" ) or die "出力ファイルオープンエラー: $!\n"; print FOUT ( $ptn, "\n" ); print FOUT ( $x, "\n" ); print FOUT ( @b ); close( FOUT ); というプログラムで実行すると C:\My Perl\pl>perl プログラムの実行.pl 入力ファイル名?sample1.txt 168 行読み込みました 検索文字列?k 45 行見つかりました 出力ファイル名?out3-24.txt 続行するには何かキーを押してください . . . となり出力ファイルの中身が表示されません。 どこを間違えているのかご指摘いただけないでしょうか?

  • bushのプログラミングについて

    をつかって、ディレクトリをコピーして、その中の いくつかを削除し 、その中のいくつかをものとのファイルへのリンクにしようと思っています。 ファイル構造は以下のような形です。 元々のディレクトリ /TEST/A/ABC ーーーーリンクする ............./DEF ーーーー削除する ............./GHI ーーーーリンクする ............./JKL ーーーー残す ........../B ーーーーAと同じ構造 ........../C ーーーーAと同じ構造 希望 /COPY/A/ABC ーーーー元へのリンク .............../GHI ーーーー元へのリンク .............../JKL ーーーーコピーされたデータ ........../B ーーーーAと同じ構造 ........../C ーーーーAと同じ構造 勉強し始めたもののまだまだ、知識部足です。ご存じの方よろしくおねがいします。 現在ようやくわかったところは、 cp -r ~/test/ /copy/ for i in $( ls ~/copy/); do ....echo 1em:$i .......for p in $( ls ~/copy/$i); do ...........# find *F | rm ...........# find ABC | ln -s ~/test/$i .......done done というような感じです。なぜかスペースが入力されないので代わりに(.)をつかいました

専門家に質問してみよう