こんばんは。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で質問しましょう!
似たような質問が見つかりました
- CGI htmlからパラメータで、cgiに渡したい。 1 2023/02/06 16:15
- Excel(エクセル) Excelにて、フォルダ内のTextファイルをマクロで統合すると文字化けしてしまう時の解消コード 4 2023/01/01 07:32
- Visual Basic(VBA) 集めたシートのシート名を変更したい。 下記のコードでサブフォルダにあるファイルのSheet3を集めて 6 2022/08/23 10:38
- その他(クラウドサービス・オンラインストレージ) Google ColabでGoogleドライブのサブフォルダにファイルを生成する方法 1 2022/10/31 17:37
- Visual Basic(VBA) サブフォルダ(データ)にある複数の.xlsxファイルのSheet3のA2セルの値で01から左側をB2 2 2022/08/14 15:46
- その他(プログラミング・Web制作) セレクトボックスで選択された値をコントローラーで使用したい 2 2022/07/26 16:41
- Visual Basic(VBA) vbaのエラー対応(実行時エラー7:メモリが不足しています) 4 2023/04/24 00:20
- Perl Perl の外部モジュールの利用方法 3 2022/07/10 18:34
- Excel(エクセル) エクセルのマクロについて教えてください。 1 2023/02/06 13:01
- Excel(エクセル) Excel VBAどこが間違ってますか? 4 2023/07/17 10:04
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
一つのテキストファイルと複数...
-
window.open でのファイル指定方法
-
フォルダ内のファイルを全て開...
-
並び方、
-
PerlでのUseless use...
-
python renameについて
-
Perlの質問:行と列を入れ替え...
-
ExcelをCSV書き出す場合のシー...
-
サーバーにある特定の拡張子フ...
-
batファイルでrenameができませ...
-
エクセルVBA コードが同じでも...
-
VBAでCSVファイルを途中行まで...
-
パスから最後のディレクトリだ...
-
VBAで巨大なファイルの途中から...
-
配列の中に重複文字列があるか...
-
VBAでCSVファイルの特定行を書...
-
2つのCSVファイルをマッチング
-
perlにて2つのファイル比較
-
openした後、closeしないでプロ...
-
エクセルVBAで素数だけを出力す...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
python renameについて
-
fgets で値が取得できない
-
window.open でのファイル指定方法
-
巨大なテキストの最終行を取得...
-
ファイル全てを .xlsm に変更し...
-
read() on unopened filehandle...
-
csvファイルの横方向への改行に...
-
VBAコードを張り付け後のエクセ...
-
Firefox で file:// で始まる U...
-
JSP URLに表示される拡張子 .jsp
-
drtファイルはどうしたら開...
-
並び方、
-
重複ファイル名ある場合ファイ...
-
VBA テキストファイルを読み取...
-
cgiでサーバーにファイルを追加...
-
HTMLのフォームで画像と文...
-
WindowsでPerlをする際,1行目の...
-
バイナリファイルの出力
-
Perlでのパーミッション変更の仕方
-
foreach内での変数の扱い?
おすすめ情報