
こんばんは。Perl超初心者です(プログラミングの初心者でもあります)。
フォルダ内にあるすべてのファイルに対して、正規表現を使った文字列置換をしたいのですが、うまくいきません。アドヴァイスをいただけないでしょうか。
具体的には、あるファルダの中に100個程のファイルがあって、その中の改行が3回連続している部分を、「改行+[SAMPLE]+改行」に置換をしたいと表います。
Windows XP Professional SP3 / ActivePerl 5.10 の環境で、以下のように記述したのですが、「Missing $ on loop variable at insert.pl line 5.」とエラーになってしまいます。どこで、間違ったのでしょうか(というか、まるでダメなスクリプトかもしれませんが…)。
use strict;
use warnings;
my @filename = glob "*.txt";
foreach open(FILE, "$filename(@filename)") {
my @content =<FILE>;
@content =~ s/\n{3}/\n[SAMPLE]\n/g;
print FILE @content;
close(FILE);
}
どなたか、ご教示いただけると非常助かります。
よろしくお願い致します。
No.4ベストアンサー
- 回答日時:
寝る直前に書いたので寝ぼけてました。
こんな感じでどうでしょう。
わからないところがあれば遠慮なく質問してください>質問者様
use strict;
use warnings;
use feature ':5.10';
use strict;
use warnings;
undef $/;
foreach my $file (glob '*.txt') {
open my $rfh, '<', $file or next;
my $tmp = "$file" . "tmp";
open my $wfh, '>', $tmp or die;
my $content = <$rfh>;
$content =~ s/\n{3}/\n[SAMPLE]\n/g;
print $wfh $content;
close $rfh;
close $wfh;
#unlink "${file}.bak"
rename $file, "${file}.bak";
rename $tmp, $file;
}
No.6
- 回答日時:
もう
http://okwave.jp/qa5526745.htmlに移ってこっちは放置かもしれませんが。わたしが#2で提示したスクリプトでは、
undef $/;
という行があるのに注意してください。
これによって、「ファイルの丸呑み」ができるようになり
my $content = <$fh>;
で、$contentにファイルの内容が丸々入ります。
#通常は一行だけ
今回はs修飾子もm修飾子もつける必要がないので(つけても構いませんが)
$content =~ s/\n{3}/\n[SAMPLE]\n/g;
で望みの置換をやってくれるはずです。
もう一つの質問も基本は同じですね。
度々のご回答、誠にありがとうございます。
最初見たときはわからなかったのですが、undef $/; の部分でレコードセパレータを無効化していたのですね。
お陰で思ったとおりの処理をすることができました。
せっかくの機会なので、今後レコードセパレータを無効化するとはどういうことなのか、掘り下げて見たいと思います。
大変勉強になりました。
No.5
- 回答日時:
勉強がてらやってみました。
use strict;
use warnings;
while ( my $file = glob '*.txt' ) {
open my $in, '<', $file or die;
my @contents = <$in>;
close $in;
my $content = join('', @contents);
open my $out, ">$file";
print $out map { s/\n{3}/\n\n[SAMPLE]\n/g; $_ } $content;
close $out;
}
FHをいきなりスカラに読み込むと最初の一行だけしか代入されず、mapは一行ごとに処理するらしく「連続した改行」が認識されず。
という事で、joinを使って配列からスカラに入れてみました。
なるほど!
そういうやり方もありますね。
正解にたどり着く道がひとつでないのがプログラミングの醍醐味、
と、生意気ならがら思ってしまいました。
ありがとうございました。
たいへん勉強になりました。
No.2
- 回答日時:
とりあえずこんな感じかな。
手抜きですが。
use strict;
use warnings;
undef $/;
foreach my $file (glob '*.txt') {
open my $fh, '<', $file or next;
my $content = <$fh>;
$content =~ s/\n{3}/\n[SAMPLE]\n/g;
print $fh $content;
close $fh;
}
試してないので間違いが入ってたらごめんなさい。
この回答への補足
サンプルリストありがとうございます。
上記では、エラーになったので以下のようにしたら、とりあえず動きました。
しかし、このやり方だと結局1行ずつ処理しているので、「\n{3}」の部分がちゃんとヒットしてくれません(/mオプションで複数行の検索にしてもうまくいきません)。私が検索したいのは、次のような部分です。
SAMPLE_STRING_ID_001<改行>
<改行>
<改行>
つまりIDの下に改行のみの場合は、[SAMPLE]という文字列を入れたいのです。
この問題を解決する良い方法はないでしょうか。
以下、現状のリスト:
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>;
close(FILE);
foreach my $line (@file) {
$line =~ s/\n{3}/\n[SAMPLE]\n/gm;
}
open(NEWFILE, "> $dir") or die "$dir: $!";
print NEWFILE @file;
close(NEWFILE);
}
closedir(DIR);
No.1
- 回答日時:
入門書の類などはお持ちでないのでしょうか?
foreach open(FILE, "$filename(@filename)") {
my @content =<FILE>;
@content =~ s/\n{3}/\n[SAMPLE]\n/g;
いくらなんでもこれはない。としかコメントのしようがありません。
なんで foreach のすぐ後ろに open が来ていたり、
=~ の左辺が配列変数だったりするんでしょうか。
#smart matchingでもこれはないよなあ。たしか。
もうひとつ、今回の例ではファイルから読み込んだ結果を配列に収めちゃだめですね。
入門書は持っています。週末に入門書片手に独学を始めて3週目です。
この質問を書いたときは、仕事中だったので手元に入門書がなく、オンラインの入門サイトなどを斜め読みしながらコソコソとやっていました。
#2のスクリプトはのちほど試させていただきます。
>いくらなんでもこれはない。としかコメントのしようがありません。
私も翻訳の仕事をしていますので、英語の質問を見るとそういう気持ちになることがあります。
しかも、英語の場合は間違いを指摘しても、受験英語のルールに固執し、間違いを認めなかったりします。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
#!/usr/bin/perlで書きだしたCG...
-
perlのrequireの動き方について...
-
perl の open について教えてく...
-
ファイルをディレクトリ分配の...
-
perlでリテラル値はメモリにど...
-
Perlでファイルの末尾から指定...
-
テキストファイルで提出とは?
-
Perlプログラムについてファイ...
-
[perl] perlで書き込み中に、PC...
-
Perl言語について。
-
アルファベットに付いて質問し...
-
Perlのエラーについてご教授く...
-
perlのflock関数でロックをかけ...
-
AI sisterとは、偽物の人ですか?
-
bashスクリプト
-
ファイルアイコンの左下に緑の□...
-
perlプログラミング 空白行削除
-
perlで2次元配列をサブルーチ...
-
Perlで時間の計算
-
perlについて
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
fgets で値が取得できない
-
drtファイルはどうしたら開...
-
MATLABのm-fileについて
-
ファイル全てを .xlsm に変更し...
-
window.open でのファイル指定方法
-
シェルスクリプトによる計算
-
どこがおかしいのか教えてくだ...
-
文字列の抽出がうまくできません
-
ファイルの読み込みと置き換え
-
VBAコードを張り付け後のエクセ...
-
PHPコードをはじめ、記号や記述...
-
python renameについて
-
巨大なテキストの最終行を取得...
-
perlのDigest::MD5;でのMD5算出...
-
WindowsでPerlをする際,1行目の...
-
正規表現で " ← を削除する...
-
正規表現の一致について
-
powerpointでwebページとして保...
-
VBA テキストファイルを読み取...
-
データフォルダ参照先
おすすめ情報