Perlでファイル処理を行う方法について

このQ&Aのポイント
  • Perlのサブルーチンではなく、forループを使用してファイル処理を行いたい場合、自由にファイル数と条件を指定して実行することは可能です。
  • 初心者でも理解しやすいように、forループの回数を指定するようにして、処理条件やファイル名を指定する際には、標準入力を使用する方法をご紹介します。
  • この方法を使用すれば、柔軟にファイル処理を行うことができます。Perlの初心者でも分かりやすいように、具体的なサンプルコードも提供します。
回答を見る
  • ベストアンサー

perlについての質問です

&あああ("ファイル名1", "AGT"); &あああ("ファイル名2", "ACA"); &あああ("ファイル名3", "TAT"); &あああ("ファイル名4", "TGA"); sub あああ{ open(FILE, "処理させるファイル") or die "$!"; my ($file, $tag) = @_; open(NEWFILE, "> $file") or die "$!"; my $x = 0; my @ti; while(<FILE>){ if($_ =~ "^>"){ $x ++; $ti[$x] = $_; } elsif($_ =~ "^$tag"){ print NEWFILE $ti[$x].$_; } } print "$x\n"; close NEWFILE; } このプログラムをサブルーチンではなく forかなんかで実行させ 自由にファイル数と$tagを設定し 実行できるようにしたいのですが できますでしょうか>< forをまわす回数を指定しSTDINなんかで指定し そのforの中でファイル処理に必要な条件や 吐き出すファイルの名前をSTDINで指定するようなものを書きたいです ちなみにperl初心者です 質問が意味不明かもしれないです>< よろしくおねがいします

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

質問者が選んだベストアンサー

  • ベストアンサー
  • kuroizell
  • ベストアンサー率55% (95/170)
回答No.1

以下を組み合わせたら何かしら出来るかと思います。 # STDINで指定 chomp( my $stdin = <STDIN> ); # forで$stdin回まわす my $name = "hoge"; for (1..$stdin) { print $name . $_ , "\n"; } # Tagを回す my @tags = qw(AGT ACA TAT TGA); foreach my $tag (@tags) { print "$tag\n"; }

その他の回答 (1)

回答No.2

コマンドラインのオプションを取り扱いたいんだと想像します。 次のスクリプトでは次のオプションが使えます。 -t LIST or --tag=LIST コンマ区切りのタグ文字列を指定します。複数回指定できます。 -o PATH or --ouput=PATH 出力ファイルのプリフィクスです。デフォルトはスクリプトの名前+'-output-'。 -n or --num 出力ファイル名の連番を数字にします。デフォルトはアルファベットです。 例: $ perl arg.pl --tag=a,b,c arg-output-a a arg-output-b b arg-output-c c $ perl arg.pl --tag=a --tag=b --tag=c --output=path- path-a a path-b b path-c c $ perl arg.pl -t a,b,c -o path- --num path-1 a path-2 b path-3 c arg.pl: #!/usr/bin/perl use strict; use warnings; use v5.10; use File::Basename; use Getopt::Long; my @tag; my $output = basename($0, '.pl') . '-output-'; my $num; GetOptions(   'tag=s' => \@tag  , 'output=s' => \$output  , 'num' => \$num ); @tag = split(/,/, join(',', @tag)); my $suffix = 'a'; if ($num) { $suffix = '1'; } foreach (@tag) { &aaa($output.$suffix++, $_); } sub aaa { # 単に引数をプリントするだけ  my ($output, $tag) = @_;  say $output; say $tag; }

参考URL:
http://perldoc.perl.org/Getopt/Long.html

関連するQ&A

  • 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 続行するには何かキーを押してください . . . となり出力ファイルの中身が表示されません。 どこを間違えているのかご指摘いただけないでしょうか?

  • perlで以下の動作が出来る機能を作っています。

    perlで以下の動作が出来る機能を作っています。 1.ファイル名が載っているfname.txtを読み込む。 2.読み込んだファイル名を開く。 3.ファイルの内容を変換。 4.変換したファイル内容をnew_fileディレクトリに保存。※ファイル名はそのまま。 1~4までを作ったのですが、fname.txtで指定した全てのファイル名を変換して保存したいのに、一番最初に記載されてあるファイル名しか置換されません。書籍などで調べてもわからないのと今日中に製作したいのでここで質問しました。 ご教授お願いします。 以下にソースを貼ります。 #!/usr/local/bin/perl -w use strict; my $x = 0; my $y = 0; my $z = 0; open(IN,"<"."fname.txt")or die "cannot open txt_file: $!";#fname.txtを開く while(<IN>){ #chomp $_;#改行してファイル名を書き込んでいるので、改行を消去 my $fn = $_; my @F = $fn; foreach my $FNAME (@F){ open(FILE,"$FNAME")or die "cannot open txt_file: $!";#fname.txtに記載してあるファイルを開く open(OUT,">". "new_file/$FNAME")or die "cannot write txt_file: $!";#new_fileを開いて書き込む while(<FILE>){#以下、ファイルの置換内容 my @d; if (m/^[X1-9]+ (.*)/s) { ($y,$z)=(0,0); $d[0] = ++$x; $d[1] = 0; $d[2] = 0; $_ = $d[0] . " " . $1; } if (m/^[X1-9]+\.[X1-9]+ (.*)/s) { $z=0; $d[0] = $x; $d[1] = ++$y; $d[2] = 0; $_ = $d[0] . "." . $d[1] . " " . $1; } if (m/^[X1-9]+\.[X1-9]+\.[X1-9]+ (.*)/s){ $d[0] = $x; $d[1] = $y; $d[2] = ++$z; $_ = $d[0] . "." . $d[1] . "." . $d[2] . " " . $1; } print OUT $_; } } close(IN); close(FILE); close(OUT); exit ; }

  • 一つのテキストファイルと複数のファイルの結合

    よろしくお願いします.ディレクトリ内の一つのテキストファイル(joint.txt)と複数のファイルの結合を行ごとに隣へ結合するプログラムを作成しています.ここで以下のプログラムを作成したのですが,うまくいかないため,誤っている部分をご指摘願えないでしょうか. my $dirname = '.'; opendir(DIR, $dirname) or die "$dirname: $!"; while (my $dir = readdir(DIR)) { next unless (-f $dir); next unless ($dir =~ /\.txt$/); open(FILE, $dir) or die "$dir: $!"; open(FILE2,"joint.txt"); my @file = <FILE>; my @file2 = <FILE2>; close(FILE); close(FILE2); foreach my $line (@file) { foreach my $line2 (@file2) { chomp $line2; $line = "$line2.",".$line"; } } open(NEWFILE, "> $dir") or die "$dir: $!"; print NEWFILE @file; print NEWFILE @file2; close(NEWFILE); } closedir(DIR);

    • ベストアンサー
    • Perl
  • perlで文書を読み込み検索置換したい

    MAC OS Xを使用しています。 検索置換のプログラムをperで作成し、Applescript上で呼び出したいのです。 実際はファイルメーカーのスクリプトの中でApplescriptを記述してその中で呼び出したいのです。 do shell script "perl ~.pl"という感じで使えるのではないかと 下記のようなサンプルスクリプトを見つけたのですが 内容の更新の仕方がよく分かりません。 perlについては全くの初心者でいろいろ調べたのですがよく理解できませんでした。 検索置換したいのですが、どういうふうに書けばいいのでしょうか。 (2)の部分を教えて下さい。宜しくお願いします。 use strict; use warnings; use File::Copy 'move'; # (1) ファイルの内容を読み込む my $file = 'F:\共有\PERL\test.txt'; open my $fh, '<', $file or die qq/Can't open file "$file": $!/; my $content = do {local $/; <$fh>}; close $fh; # (2) 内容の更新 ▼をリターンに置き換えたいのです。 $line =~s/▼/\n/; # (3) 一時ファイルへの書き出し my $temp_file = "$file.$$." . int(rand 10000); open my $temp_fh, '>', $temp_file or die qq/Can't open file "$file": $!/; print $temp_fh $content; close $temp_fh or die qq/Can't open file "$file": $!/; # (4) 一時ファイル名を元のファイル名に変更 move $temp_file, $file or die qq/Can't move "$temp_file" to "$file": $!/;

  • 指定の行数目から行を抽出する

    いつもお世話になっております. 環境はWindows XP Pro でActiveperlを使っています. Perlでしたいことは,「指定の行数目から行を抽出する」ことです. 具体的には以下のようにしたいと思っております. data.txt A B C D E F line.txt 2 4 6 output.txt B D F 先ほどある方からサンプルソースを教えてもらったのでそれをベースに作ってみましたが,出力のoutput.txtが空のままです. use strict; use warnings; use feature ':5.10'; use IO::File; open my $file2, '<', 'line.txt' or die "can't open input $!"; chomp(my @subjects = <$file2>); close $file2; open my $newfile, '>>', 'data_out.txt' or die "can't open output $!"; open my $file, '<', 'data.txt' or die "can't open input $!"; while (my $line = <$file>) { chomp $line; foreach my $line (@line) { print $line; if ($. eq $subjects){ say {$newfile} $line; } } } close $file; close $newfile; どこが間違っているのでしょうか.ご指摘ください.よろしくお願いします.

    • ベストアンサー
    • Perl
  • perl言語のプログラム不良

    あらかじめ作った英語のテキストファイルを入力し、 文字数をカウントするプログラム(perl言語)でつくっています。 あらかたできたと思うのですが、 明らかに100文字以上あるにも関わらず なぜか3文字とカウントされます。 どこが不具合がわかる方いましたら よろしくお願いいたします。 以下が問題のプログラムです。 print"読み込むファイル名を入力してください。\n"; $input_file = <STDIN>; open(INPUT, "$input_file") or die "$!"; sub count_words{ my @ words = split(/\W+/,$_[0]); my $num_words=@ words; } $num_words = &count_words($input_file); print"単語数は$num_wordsです。"; close(INPUT);

  • ディレクトリ内のテキストファイルに対する同一処理

    よろしくお願いします。現在Linuxの環境でテキスト処理をしております。 ディレクトリ内にファイル名の異なった以下のような大量ファイルがあります。 a.txt 0,1,2,3,4,5,6,7 1,2,3,4,5,6,7,8 b.txt 2,3,4,5,6,7,8,9 3,4,5,6,7,8,9,10 これらのファイルをカンマでsplitし、左から2番目の数にだけ1を引き,下のディレクトリであるoutに出力させます。出力は以下のようになります。 ./out/a.txt 0,0,2,3,4,5,6,7 1,2,3,4,5,6,7,8 ./out/b.txt 2,2,4,5,6,7,8,9 3,4,5,6,7,8,9,10 そこで以下のようなPerlのプログラムを作成しました。 use strict; use warnings; my $dirname = '.'; opendir(DIR, $dirname) or die "$dirname: $!"; while (my $dir = readdir(DIR)) { next unless (-f $dir); next unless ($dir =~ /\.txt$/); print $dir, "\n"; open(FILE, $dir) or die "$dir: $!"; my @file = <FILE>; foreach $line (@file) { my ($a,$b,$c,$d,$e,$f,$g,$h) = split(/,/, $line);      my $b = $b - 1; close(FILE); } open(NEWFILE, "> ./out/$dir") or die "$dir: $!"; print NEWFILE @file; close(NEWFILE); } closedir(DIR); ですが、出力は完了するのですが、元のファイルから計算がされていません。どこがどう間違えているのかご指摘よろしくお願い申し上げます。

    • ベストアンサー
    • Perl
  • for文の応用

    今、S001.csvからS099.csvまでのファイルがあります。 これを下記のプログラムを書いて、新たにSA001.csvからSA099.csvまでのファイルを作りたいと考えています。 しかし、途中途中で数字が抜けているため、全てのファイルが処理できず 困っています。たとえば、S001.csvからS009.csvまでは 存在するが、S010.csvはなく、またS011.csvからは 存在するという具合です。 初歩的な質問で大変恐縮ですが、ご教示いただければ幸いです。 for ($i = 1; $i <= 99; ++$i) {  $file = sprintf("S%03d.csv", $i);  $newfile = sprintf("SA%03d.csv", $i); open (FILE, $file) or die; open (NEWFILE, ">$newfile") or die;  while (my $line = <FILE>) {  my ($aaa, $bbb, $ccc) = split(/,/, $line);  print NEWFILE join(',', $aaa, $bbb), "\n";  } close(FILE); close(NEWFILE); }

    • ベストアンサー
    • Perl
  • プログラムの高速化

    いつもお世話になっております.以下のプログラムをできるだけ高速化したいと思います. use warnings; use strict; my $dirname = '.'; opendir(DIR, $dirname) or die "$dirname: $!"; while (my $dir = readdir(DIR)) { next unless (-f $dir); next unless ($dir =~ /\.txt$/); open(FILE, $dir) or die "$dir: $!"; while (my $line = <FILE>) { my ($a,$b,$c,$d,$e,$f) = split( /,/ , $line ); my $name = $a.",".$b; open(NEWFILE, ">> ./out/$name.txt") or die "$dir: $!"; print NEWFILE $line; close(NEWFILE); } } close(FILE); closedir(DIR); やっていることは,ディレクトリ内のテキストファイルを読み込んでいって,splitでカンマ区切りにした,$a,$bをファイル名として下のディレクトリのoutに保存していくというものです. ファイル数が数千あり,各ファイルも数千行となるため,このソースを高速化する方法はありますでしょうか.ご回答よろしくお願いします.

    • ベストアンサー
    • Perl
  • Perlでのファイル入出力、処理方法

    メモ帳で以下のようなプログラムを書きました。(file_1.plで保存しました) #!/usr/bin/perl $file="data.csv"; $cityfile="name.txt"; $outfile="data_out.csv"; open (IN, $file) or die "$!"; open (FILE, $file) or die "$!"; open (OUT, ">$outfile") or die "$!"; @city = <FILE>; ・ ・ ・ これをCygwinコマンド上で、 perl file_1.pl と入力し、Enterを押すと「No such file or directory at file_1.pl line 9.」と表示されます。 line9はopen (FILE, $file) or die "$!";という文です。 どこが間違えで、どのように修正すればよいのでしょうか。 よろしくお願いします。

専門家に質問してみよう