• ベストアンサー

ファイルの作成と書き込み

今始めてPerlを書いているのですがつまづいている部分があります。 変数に記録されたデータをテキストファイルとして出力する部分なのですが保存するテキストファイルを上書きしないようにしてほしいのです。 私が希望する流れを簡単に説明すると・・・。 変数「$txt」にデータを記録。 ↓ フォルダー「log」に移動。(開く。) ↓ ファイル「1.txt」の存在を確認。 ↓ (存在しなければ) 「1.txt」を作成。中身は「$txt」 ↓ (存在すれば) 「2.txt」の存在を確認。 ・ ・ ・ これを10回ループ ・ 「12.txt」の存在を確認。 (存在しなければ) 「12.txt」を作成。中身は「$txt」。 (存在したら) 「1.txt」を「$txt」で上書き 説明下手なのですがどなたかわかるかたソースを教えていただけませんか?

  • Perl
  • 回答数7
  • ありがとう数33

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

  • ベストアンサー
  • ak9457
  • ベストアンサー率100% (1/1)
回答No.6

2つの命令とはBLUEPIXYさんと私の紹介した命令の事でしょうか。 つなげるという意味がわかりませんでしたが一応この二つを使って作ってみました。 処理の流れはmr_flogmanさんのを参考に1~12のファイル存在を確認しすべて存在すればソートして一番古いファイルに書き込んでます。 処理内容にあまり自信がありませんが、宜しければ参考にして下さい。 my $txt="HOGEHOGE"; my $max_file_num=12; my $name; chdir("log"); my $flg = 0; for( 1..$max_file_num ) { $name = "$_\.txt"; if( !(-e $name) ) { $flg = 1; last; } push(@files, $name); } if ( $flg != 1 ) { $name = (sort{ (stat($a))[9] <=> (stat($b))[9] || $a cmp $b }@files)[0]; } open(HDL, "> $name"); print HDL $txt; close(HDL); print "$nameにデータを書き込みました。\n";

その他の回答 (6)

  • leaz024
  • ベストアンサー率75% (398/526)
回答No.7

要するに「最新データ+11世代のバックアップ」という形で保存したい、ということですよね? ところで、「1~12.txt を使って」とのことですが、質問の方法だと保存の度に最古のファイルを探さなければならないし、使う時にも最新のファイルを探さなければなりません。 そこで提案なのですが、ファイル名の数字をデータの新鮮度とし、1.txt が最新、2.txt が1つ前の状態、3.txt が2つ前・・・、というようにしてはどうでしょうか? これなら一々ファイルの更新日時を調べる必要がありませんし、保存時も 1.txt 生成の前に 1~11.txt を 2~12.txt にリネームするだけです。 my $generations = 12; chdir "log"; # バックアップ世代の更新 for (my $src = $generations-1; $src; --$src) {   my $dst = $src + 1;   rename "$src.txt"=>"$dst.txt" if -e "$src.txt"; } # 最新データの保存 open FH, "> 1.txt" or die $!; print FH $txt;       # $txt は、定義済みとする。 close FH; ※コードを見やすくするためインデントなどに全角空白を使っているので、コピーされる場合はタブなどに置換して下さい。

fouhttp
質問者

お礼

みなさん有難う御座いました。 ポイントについては投稿順につけさせていただきました。 leaz024さん、ポイントつけられませんでした。 すいません。 結果的にどの方法を採用するかはまだ決められないのですがleaz024さんの方法も便利かなと思っています。 有難う御座いました。

回答No.5

たびたびすみません。。。 バグッたソースをまたペーストしてしまいました。。。 orz............... 正確には、 #!/usr/bin/perl -w use strict; my $txt="HOGEHOGE"; my $max_file_num=12; my $name; chdir "log"; my $flg = 0; for(1..$max_file_num) { $name = "$_".".txt"; if( -f $name) { print "$_.txtは存在します\n"; } else { print "$_.txtにデータを書き込みました。\n"; open HDL, " > $name" or die $!; print HDL $txt; close HDL; $flg = 1; last; } } if ( $flg != 1 ) { open HDL, "/bin/ls -rt1 *.txt|/bin/tail -1|" or die $!; my $write_name = <HDL>; chomp $write_name; close HDL; open HDL, "> $write_name" or die $!; print HDL $txt; close HDL; print "$write_name"."にデータを書き込みました。\n"; }

回答No.4

下の者です。 先ほどの回答バグってました。。。 #!/usr/bin/perl -w use strict; my $txt="HOGEHOGE"; my $max_file_num=12; my $name; chdir "log"; for(1..$max_file_num) { $name = "$_".".txt"; if( -f $name) { print "$_.txtは存在します\n"; } else { print "$_.txtにデータを書き込みました。\n"; open HDL, " > $name" or die $!; print HDL $txt; close HDL; } } open HDL, "/bin/ls -rt1 *.txt|/bin/tail -1|" or die $!; my $write_name = <HDL>; chomp $write_name; close HDL; open HDL, "> $write_name" or die $!; print HDL $txt; close HDL; print "$write_name"."にデータを書き込みました。\n";

回答No.3

お使いのOSがUNIX系だったら、以下の方法が簡単かもしれません。 もしそうでなければ、ak9457さんのおっしゃるとおり、 stat関数を使用して、日付、ファイル名の順で、ソートするロジックを作って、一番古い日付で、もし同一日付だったら、1番若い番号の順にデータを上書きするのがよいと思います。 #!/usr/bin/perl -w use strict; my $txt="HOGEHOGE"; my $max_file_num=12; my $name; chdir "log"; for(1..$max_file_num) { $name = "$_".".txt"; if( -f $name) { print "$_.txtは存在します\n"; } else { print "$_.txtにデータを書き込みました。\n"; open HDL, " > $name" or die $!; print HDL $txt; close HDL; } } open HDL, "/bin/ls -rt1 *.txt|/bin/tail -1|" or die $!; my $write_name = <HDL>; chomp $write_name; close HDL; open HDL, "> $write_name" or die $!; print HDL $txt; close HDL; print "$write_name"."にデータを書き込みました。\n";

  • ak9457
  • ベストアンサー率100% (1/1)
回答No.2

(stat($filename))[9]で最終更新日を得られるのでこれをつかってみてはいかがでしょうか。

fouhttp
質問者

補足

2つの命令をつなげてみようと思っているのですが どうも上手くつながりません。 どうすれば上のような処理ができるのでしょうか。

  • BLUEPIXY
  • ベストアンサー率50% (3003/5914)
回答No.1

1~12のファイルが全て存在するとき、 常に1.txtだけに出力されるような気がしますが、 それは、置いておいて カレントディレクトリを移動するには chdir "log"; の様にします。logの部分はフルパスで。 -e "1.txt" でファイルが存在する場合(真:1)ということになります

fouhttp
質問者

補足

あっ、そうですね。 1~12のファイルが全て存在する場合 古い順に上書きしていきたいのですがどうすれば 良いのでしょうか。

関連するQ&A

  • ファイルの作成方法…

    VBでテキストファイルの中身を開くプログラムを作成しました。 そのテキストファイルの中身を変更(編集)し、それを同じファイルに上書き保存するのではなく、開いたファイルのある同じフォルダ内に新しいファイルを作り保存したいと思っています。  <例>test1.txtというファイルを開き中身を編集してそれを同じフォルダ内に新しくtest2.txtというファイルを作って保存するといった感じです。 そこで新しいファイル名で保存する(新しいファイルを作成する)方法を教えて欲しいんです、こんな説明で分かってもらえるか不安ですが…、どなたか分かる方教えていただけませんでしょうか? かなりの初心者なのですが、私でも理解できるようなプログラムだと嬉しいです。 よろしくお願いします。

  • ファイルへ書込み

    こんにちわ。 ■質問1 ファイルへの書込み(書替え)をどうやってやればいいか悩んでいます。 既に存在する aaa.txt という名前のファイルがあるとします。 aaa.txtをファイルオープンし、ある文字列をキーに検索し、 値を書替えたいのです。 以下の例の様にaaa.txtに、書かれているとします。 例)aaa.txtファイルの中身 LOOP_CNT1=50 LOOP_CNT2=100 LOOP_CNT3=200 LOOP_CNT4=300 LOOP_CNT5=400 "LOOP_CNT3"という文字列をキーに、ファイルから対象文字列を検索し、設定値の 200 を 10000 に書き換えたいのです。 書き換える値、10000 はパラメータから取得します。 書き換えれる場合、それ以降の文字列の値が 上書かれてしまったり、領域を壊してしまったりはしないでしょうか? いい方法があったら教えてください! ■質問2 新規でオープンしたファイルに、 DBからループ処理で取得した値を書き込む処理を行うとします。 ※データは何件あるか分からず、なくなるまで処理します。 エラーが起きた場合のみ、ファイル書込み処理を行っていても 最終的には何も書かれていない0バイトファイルを作成したいのですが どのようにやればいいでしょうか? ※一時的にテンポラリ領域に、格納してエラーがなかった場合のみ ファイルへ書込む場合、テンポラリはどのような持ち方をすれいいで しょうか? テンポラリ用にchar型の変数を用意? データが何件あるか分からないので、 変数のサイズはどのように宣言すればいいですか? そもそも考え方が間違っていますか?

  • ファイル操作について、テキストファイルの書き換え

    よろしくお願いします。 データファイルAからデータを取得して、テキストファイルBの内容の一部を取得したデータで書き換えるという操作を行うプログラムを作りたいです。 具体的には、 データファイルA[A.txt]の中身 111 222 333 444 テキストファイルB[B.txt] 文字列1="123" 文字列2="234" 文字列3="345" 文字列4="456" というような二つのファイルを読み込み、B.txtの""で囲まれた部分を、A.txtで取得したデータで置き換えるような操作を行いたいのですが・・。 使用する言語としてはスクリプト言語であるperl、もしくはプログラム作成経験があるCを使用しようと思っています。(perlは未経験で入門書を読んでいるレベル)

    • ベストアンサー
    • Perl
  • ファイル操作について

    パールを使っています. ファイルをオープンする際に,forループでまわして 「1.txt」,「2.txt」,「3.txt」・・・ というファイルを連続でオープンさせたいのですが, どうすればいいのでしょうか? 数字を変数$aとして, ="./$a.txt" とやってもできませんでした. まったくわからないので,よろしくお願いします.

  • ファイルの中身に対する再帰的検索

    初心者です。 テキストファイルの中身を調べて、その中に特定の拡張子を持ったファイル名があれば更にその中身を調べていって、階層構造になったファイルを全て調べあげるスクリプトを作ろうとしています。 例えばfile1.txtの中身が ... hoge file2.txt file3.txt hogehoge ... だったとすれば、今度はfile2.txtおよびfile3.txtの中身に.txtという拡張子を持ったファイル名があるかどうか調べ、該当するものが無くなるまで調べていきます。 これらのテキストファイルは全て同じディレクトリ内に存在します。 どういう具合のループにすればよいのか想像がつきません。 アドバイスお願いします。

    • ベストアンサー
    • Perl
  • ファイル書込みで一行もしくは部分的に上書きする

    教えて下さい。 下のようなテキストデータがあります(sample01.txtとします) (内容) 1111000000000000 1111000000000000 1111000000000000 これを 1111000000000000 1111001111110000 1111000000000000 と言うふうに2行目もしくは部分的に上書きして保存したいです。 よろしくお願いします。

    • ベストアンサー
    • PHP
  • ファイルの中身の参照

    テキストファイル(DB.txt)の中身を参照する事が出来ません。 テキストファイルの中身にAと書いてあったら、Aドライブにバックアップするようにするのが目的です。 X(変数)ドライブにバックアップするトコまではできてます。 Dim X As String X = ここの部分がわからない。 よろしくお願いします。

  • C#でテキストファイルの更新がしたい

    C#でテキストファイルを読込み、特定の文字を置換して上書きしたいです。 StreamReaderで読み込んで、変数に退避し、StreamWriterで書くのは出来ると思いますが もっと簡単に、読み込んでRewriteのようなコーディングって出来ないのでしょうか? A.Txt あああ いいい ううう ↓ 【あああ】を【えええ】にしてA.Txtを上書き A.Txt えええ いいい ううう 何かいい方法があれば教えてください。 よろしくお願いいたします。

  • 外部パラメータを使用したファイルの作成・書き込み

    テキストファイルに以下の内容が書かれています。 ファイルパス:/aaa/bbb/ccc ファイル名:ファイル.txt これを読み込んで $filepath = /aaa/bbb/ccc $filename = ファイル.txt となっています。 この時(「ファイル.txt」は存在しません。)、以下のような処理を行うと「/aaa/bbb/ccc」ではなく、「/aaa/bbb」に「ファイル.txt」が作成されるのですが、なぜでしょうか?? open(TXT, ">> $filepath/$filename"); flock(TXT, 2); print TXT $header; flock(TXT, 8); close(TXT); この処理の前に$filepathの値を調べましたが、確かに「/aaa/bbb/ccc」となっています。 何か注意する点や、ここが問題では?と言うようなことがあれば教えてください。

    • ベストアンサー
    • Perl
  • ディレクトリ内の全ファイルをオープンする方法

    特定のディレクトリ内に存在する全てのファイルを順次オープン・クローズするプログラムを作成したいと思います。 例えば、特定のディレクトリに下記のファイルがあるとします。 A.txt B.txt このときにA.txtをオープンし内容を読み込みクローズし、次にB.txtを同じようにオープンし内容を読み込んでクローズするプログラムです。内容を読み込んで処理する部分は問題なく、また上記のように存在するファイルが決まっていれば何も問題はないのですが、下記の場合にはどのように存在するファイルを探せばよいのかがわかりません。 ・何ファイルあるかわからない ・存在するファイルは必ずテキスト ・ファイル名は決まっていない(perlで問題なく読み込めるファイル長) なお、特定のディレクトリに存在するファイルを順次全て読み込めればよいので、その読み込む順番にこだわりはありません。 どうぞよろしくお願い致します。

    • ベストアンサー
    • Perl

専門家に質問してみよう