• 締切済み

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": $!/;

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

みんなの回答

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

> # (2) 内容の更新 ▼をリターンに置き換えたいのです。 > $line =~s/▼/\n/; ここの置換内容のことなら、Perlの本を買ってきたり(できればラクダ本クラスのまともなやつ)「perl 正規表現」で検索したりして覚えてください。数例挙げる程度ならともかく、詳細をここに説明できるもんじゃないです。 一応、文字コードが正しければ、コメント通りの動作をするはずですが。 うまくいかないなら、どううまくいかないか、詳細に補足してください。 あと、 > my $file = 'F:\共有\PERL\test.txt'; これで入力ファイルを指定していますが、その指定方法がWindows用ですね。

ADJUSTLIGHT
質問者

お礼

勉強不足ですね。もうちょっと頑張ってみます。 早速本を購入してみたいと思います。 それでもわからない時に質問させていただきます。

関連するQ&A

  • perlのDigest::MD5;でのMD5算出が異なる

    perlのDigest::MD5;でのMD5算出が異なる 下記、スクリプトをレンタルサーバ上と、WindowsOS上で走らせてみたところ、おなじファイルにも関わらず、MD5が異なります。 何故でしょうか? #!/usr/local/bin/perl use strict; use warnings; use Digest::MD5; my $file = 'test.zip'; my $ctx = Digest::MD5->new; open my $fh, "<$file"; $ctx->addfile($fh); my $md5 = $ctx->hexdigest; close($fh); open my $fh2, ">>md5.txt"; print $fh2 "$file $md5\n"; print "$file $md5\n"; close $fh2;

    • ベストアンサー
    • Perl
  • ファイルのアップローダーを動作させたい。

    ファイルをサーバーへ格納するプログラムを検索して作成しました。 見よう見まねなのでおかしい部分があるかもしれません。 entry.cgi #!/perl/bin/perl my $buffer; my $query = CGI->new; my $fh = $query->upload('file') or die(qq(Invalid file handle returned.)); # Get $fh my $file = $query->param('file'); my $file_name = ($file =~ /([^\\\/:]+)$/) ? $1 : 'uploaded.bin'; open(OUT, ">$file_name") or die(qq(Can't open "$file_name".)); binmode OUT; while (read($fh, $buffer, 1024)) { # Read from $fh insted of $file print OUT $buffer; } close OUT; sample.html <HTM><BODY> <FORM METHOD="POST" ENCTYPE="multipart/form-data" ACTION="./entry.cgi"> <TABLE BORDER="1"> <TR><TD ><B>CSVファイル</B></TD> <TD ><INPUT TYPE="FILE" NAME="filename"></TD></TR> <TR></TR> </TABLE> <BR> <BR> <INPUT TYPE="SUBMIT" NAME="GO" VALUE=" 登録の実行 "> </FORM> </BODY></HTML> 上記のプログラムを実行すると 「CGIWrap Error: Script Execution Failed」と表示されてしまいます。 500のサーバーエラーと同じと調べてわかったのですが、どこがどうおかしいのか?わかりません。 perlの記述が今まで自分が使用していたものと勝手が違うので分からない状態です。 アドバイスもらえると幸いです。

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

    いつもお世話になっております. 環境は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
  • DBIモジュールと Perl5.8

    Perl5.8のエンコードが理解できずに困っております。 MySQLでは、utf8の文字コードのデータがあります。 以下のスクリプトを実行させると、 Wide character in print at C:/usr/local/site/lib/DBI.pm line 1008. となります。 対処方法はあるのでしょうか? use utf8; use strict; use DBI; my $dbh = DBI->connect("dbi:mysql:dbname=test", "root", "", { AutoCommit=>1, PrintError=>1, RaiseError=>1} ); my $fname = "test.txt"; my $sth = $dbh->prepare("select id, namae from test order by id asc;"); $sth->execute(); # 出力ファイルを開く。 open FILE, ">" , $fname or die "Can't open $fname: $!"; # 整形された結果をファイルにダンプする。 my $rows = $sth->dump_results(80, "\n", ",", \*FILE); # 出力ファイルを閉じる。 close FILE or die "Error closing result file: $!\n"; $dbh->disconnect();

    • ベストアンサー
    • 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 "$!";という文です。 どこが間違えで、どのように修正すればよいのでしょうか。 よろしくお願いします。

  • コマンドライン引数で正規表現を指定したい

    Perlでgrep -Aのようなことがしたいです。 ---------------grep.pl------------------------------- use strict; use warnings; #コマンドライン引数の確認 if(@ARGV != 3){ die "USAGE: \0 [num] [regex] [file]"; } #数字の読み込み my $num = $ARGV[0]; #正規表現の読み込み my $regex = qr/$ARGV[1]/; #ファイル名の読み込み my $file = $ARGV[2]; #該当行を保存する配列 my @lines = (); open my $fh, '<', "$file" or die "$!"; my @file = <$fh>; close $fh; for(my $i=0; $i<@file; $i++){ if($file[$i] =~ /$regex/){ push @lines, $file[$i]; for(my $j=1; $j<=$num; $j++){ if($i+$j < @file){ if($file[$i+$j] !~ /$regex/){ push @lines, $file[$i+$j]; }else{ last; } }else{ last; } } } } foreach my $item (@lines){ print $item; } ------------------------------------------------- ところが、正規表現がうまく読み込めません。 perl grep.pl 2 \d{4}\/\d{2}\d{2} test.txt などとしても、\d{4}\/\d{2}\d{2}の部分が機能しません。 コマンドライン引数から正規表現を指定するにはどうしたらよいでしょうか。

    • ベストアンサー
    • Perl
  • 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 ; }

  • perlでパスが通らない?

    環境はwindowsXPです。 パスがうまく通っていないようです。perl.exeが入っているファイルへのパスは正常に働いているのに、自分で作ったファイルを置いているC:\documents and settings\user\my document\perlというファイルへのパスがうまくはたらきません(Can't open perl script "test.pl": No such file or directoryと表示されます) コマンドプロンプトで「path」を使ってみても上記のフォルダはちゃんとPathに記述されています(;も入っています)。 何がいけないのでしょうか?

  • 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初心者です 質問が意味不明かもしれないです>< よろしくおねがいします

    • ベストアンサー
    • Perl
  • perlでCSVをソートする方法について

    perl初心者です。いつもありがとうございます。 perlでcsvファイル(1行のカラム数は200)、総行数は約3万行のファイルを37番目のカラム(-25以上25未満の数値データ)で降順ソートしその値によって行数がだいたい均等になるよう3分割し、2番目のカラムに文字でも数字でもよいのですがその4つのグループごとにフラグ(例えば1,2,3)を入れたいと思ってます。グループ化については境目の37番カラムの値は重複している場合が多いと思うのですがその場合は下(別に上でもかまいません)に入れるものとします。 ソートロジックは過去の質問を参照して理解しましたがグループ化しフラグを入れるルーチンがうまく作れません。下記のように作ったのですがこの先同じことを何度もやらなくてはならないので先に進めません。どなたかお助けください。最終的にやりたいことはカラム37でグループ化→カラム2にフラグを立てる、次にカラム2とカラム38(-25から0までの数値)でソートし同様に同じ行数になるようにグループ化→カラム3にフラグを立てる、さらにカラム2とカラム3とカラム39(-25以上25未満の数値データ)でソートし・・・同様に繰り返し最終的に1グループが100件(行)~150件(行)になるようにしたいのです。つまり約3万件のデータを3*4*2*4*2=192分割(5列の値で分類)したい、そしてどのような範囲で分割したかという情報も得たいのです。 use strict; use warnings; use utf8; use Encode; binmode STDOUT, ':encoding(utf-8)'; my $dir = './data'; # 処理するディレクトリ my $motoFile = 'customer.txt'; # もとファイル open my $fh, '<:encoding(cp932)', "$dir/$motoFile" or die 'ファイルが開けません。',"$!"; my %sorted; while (my $line = <$fh>) { my $key = (split /,/, $line)[37]; push @{$sorted{$key}}, $line; if (@{$sorted{$key}} == 1000) { open OUT, '>>:encoding(cp932)', "$dir/$key.tmp" or die "Can't open: $!"; print OUT @{$sorted{$key}}; close OUT; @{$sorted{$key}} = (); } } open OUT, '>:encoding(cp932)', "$dir/out.txt" or die "Can't open: $!"; foreach my $key (sort { $b <=> $a } keys %sorted) { if (-e "$key.tmp") { open IN, '<:encoding(cp932)', "$dir/$key.tmp" or die "Can't open: $!"; print OUT while <IN>; close IN; } print OUT @{$sorted{$key}} if @{$sorted{$key}}; } close OUT; #↓↓↓↓ここからフラグを作成するルーチン # 行数を調べ3つに分けるルーチン my @colum37; open IN, '<:encoding(cp932)', "$dir/out.txt" or die 'ファイルが開けません。',"$!"; my @in = <IN>; close IN; my $gyousuu = scalar(@in); my $amari = $gyousuu % 3; if ($amari == 0) { my $groupGyousuu = ($gyousuu-$amari)/3; print "総行数は$gyousuu","で、1グループの行数は$groupGyousuu","ほど、余りは$amari\n"; # あまりが0の時、group1は@inの0行 ~$groupGyousuu-1行まで #         group2は@inの$groupGyousuu行 ~$groupGyousuu*2-1行まで #         group3は@inの$groupGyousuu*2行~$groupGyousuu*3-1行まで foreach my $num (1..2) { push @colum37, (split /,/, $in[$groupGyousuu*$num])[37]; # これは境目の先頭の37番目 } print "@colum37\n"; #これでここまでは完成、分けるべき値がこの配列に入っている。 open OUT, '>:encoding(cp932)', "$dir/out.txt" or die "Can't open: $!"; foreach my $line (@in) { my @line = split /,/,$line; if ($line[37]>=$colum37[0]) { $line[1] = 1; }elsif ($line[37]>=$colum37[1] and $line[37]<$colum37[0]) { $line[1] = 2; }elsif ($line[37]<$colum37[1]) { $line[1] = 3; } $line = join (',',@line); print OUT $line; } close OUT; } elsif ($amari == 1) { この後未作成

    • ベストアンサー
    • Perl

専門家に質問してみよう