よろしくお願いします。ディレクトリ内のファイル名をテキストデータを参照として変更したいと思っております。まず、以下の参照テキストがあります。
sansyo.txt
1,2,1
2,3,1
3,4,2
4,5,3
6,7,9
・
・
・
・
このファイルを利用してディレクトリ内のファイルを以下のようにリネームします。
1,2.txt → 1,2,1.txt
2,3.txt → 2,3,1.txt
3,4.txt → 3,4,2.txt
4,5.txt → 4,5,3.txt
6,7.txt → 6,7,9.txt
・
・
・
・
・
ここで私は以下のプログラムを作成しました。
sansyo.pl
------------------------------
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: $!";
open(FILE2,"sansyo.txt");
my @file = <FILE>;
my @file2 = <FILE2>;
close(FILE);
close(FILE2);
foreach my $line2 (@file2) {
my ($a,$b,$c) = split(/,/, $line2);
if ($dir == $a.",".$b.".txt"){
rename ($dir, $a.",".$b.",".$c.".txt");
}
}
}
closedir(DIR);
内容は、FILE2にsansyo.txtをforeachで1行ずつ読み込んでいき、
$a,$b.txtというファイルが$dirに読み込んだファイルにあったら、
$a,$b,$c.txtというファイルにリネームするという内容です。
ですが、いろいろ試行錯誤したもののうまくいきません。
具体的には、
Argument "1,2.txt" isn't numeric in numeric eq (==) at sansyo.pl line 23.
とエラーがでて
if ($dir == $a.",".$b.".txt"){
この部分でエラーが発生しているようです。
どなたか解決方法をよろしくお願いします。
No.5ベストアンサー
- 回答日時:
すみません, 言い忘れていたことがあります.
ロジックとしては間違っていない (かもしれない) ですが, 「普通の書き方」ではないです.
まず, ファイル sansyo.txt をディレクトリに存在する全てのファイルに対して毎回読み直してますが, 普通に考えたらこれは無意味です. 最初に 1回だけ読めばいいはず.
また, eq で比較するのではなく, sansyo.txt の内容から適切なハッシュを作るのが常道でしょう.
まとめると, 最初に
my %cvt;
open(FILE2,"sansyo.txt");
for my $line (<FILE2>) {
chomp($line);
my ($a, $b, $c) = split(/,/, $line);
$cvt{"$a,$b.txt"} = "$line.txt";
}
として「$cvt{リネーム前} = リネーム後」という形でハッシュ %cvt を作っておき, あとは
for my $dir (readdir(DIR)) {
next unless -f $dir;
rename($dir, $cvt{$dir}) if defined $cvt{$dir};
}
とするのが普通じゃないかなぁ.
Tacosan様、pick52様
ご回答ありがとうございました。別件で多忙だったため、コメントが遅れました。なるほど、確かに無駄なプロセスを組み込んでいましたね。どうも初心者なもので、今ある知識だけで組んだものなので非常に勉強になりました。感謝いたします。
No.4
- 回答日時:
>>Tacosanさん
> grep じゃなくて glob>#2
そのようですね。
すみません、間違えました。ご指摘ありがとうございます。
ActivePerlなどでも内部的にバッチで対応しているみたいですね。
返信ついでに調べてみるとディレクトリ内のファイル検索方法って
他にもいくつかあるみたいですね。
http://perl-mongers.org/2008/05/opendirglobfilef …
No.2
- 回答日時:
関係ないのですがファイル名に半角カンマって使用できたんですね。
でもあまり使用しない方がいいような気も。
実はディレクトリないのファイル名はopendirを使用しなくても
while(<*>) {
print "$_\n";
}
これで取得できたりします。
(これって確かgrep関数の省略形だったような気が...)
# 微妙にopendirと動作が異なるので注意
# 1. カレントディレクトリ(.)と親ディレクトリ(..)は取得されません
# 2. 絶対パスまたは相対パスで指定するとその部分まで取得されます
# 他にもあるかも
# なので適材適所で使用した方がいいでしょう
# (上記の方法の方が簡単だけどopendirの方がより厳密に操作できる)
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
関連するカテゴリからQ&Aを探す
おすすめ情報
- ・漫画をレンタルでお得に読める!
- ・人生のプチ美学を教えてください!!
- ・10秒目をつむったら…
- ・あなたの習慣について教えてください!!
- ・牛、豚、鶏、どれか一つ食べられなくなるとしたら?
- ・【大喜利】【投稿~9/18】 おとぎ話『桃太郎』の知られざるエピソード
- ・街中で見かけて「グッときた人」の思い出
- ・「一気に最後まで読んだ」本、教えて下さい!
- ・幼稚園時代「何組」でしたか?
- ・激凹みから立ち直る方法
- ・1つだけ過去を変えられるとしたら?
- ・【あるあるbot連動企画】あるあるbotに投稿したけど採用されなかったあるある募集
- ・【あるあるbot連動企画】フォロワー20万人のアカウントであなたのあるあるを披露してみませんか?
- ・映画のエンドロール観る派?観ない派?
- ・海外旅行から帰ってきたら、まず何を食べる?
- ・誕生日にもらった意外なもの
- ・天使と悪魔選手権
- ・ちょっと先の未来クイズ第2問
- ・【大喜利】【投稿~9/7】 ロボットの住む世界で流行ってる罰ゲームとは?
- ・推しミネラルウォーターはありますか?
- ・都道府県穴埋めゲーム
- ・この人頭いいなと思ったエピソード
- ・準・究極の選択
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
ifstream/ofstream について
-
ファイル名を複数個配列で確保...
-
Perlで特定行から特定行までを...
-
VBAでCSVファイルの特定行を書...
-
batファイルでrenameができませ...
-
エクセルVBA コードが同じでも...
-
ExcelをCSV書き出す場合のシー...
-
VBAでCSVファイルを途中行まで...
-
fopenでディレクトリ内の全ファ...
-
chdirがうまくできない
-
open中のファイルをrename
-
FindFirstFileとFindNextFileで...
-
VBAでタブ区切りテキストの保存...
-
makefileでファイルをコピー(...
-
sprintfについて
-
openした後、closeしないでプロ...
-
Perl cgiの文字化けを直したい ...
-
C言語で特定の行を抽出する方法...
-
タブの色を変更する方法
-
readdir()で得られるファイル・...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
「パスが見つかりません」とい...
-
ファイル名を複数個配列で確保...
-
perlで先頭の数値をみて昇順に...
-
Perl エラーログを指定の場所...
-
Pythonでegrep機能をつかいたい
-
Visual Basicを使って三平方の...
-
perlでCSVをソートする方法につ...
-
ifstream を利用した1行分のテ...
-
Pythonで非日本語のUnicode文字...
-
perlプログラム 外部複数ファ...
-
Perlによるディレクトリ内の連...
-
system関数と引数について
-
C++でのテキストファイル読み込...
-
Perlのワンライナーをスクリプ...
-
バッチファイルでテキストファ...
-
Perl 重複カウント 上位3名
-
perlで指定範囲を複数ファイル...
-
perl 計算結果をファイルへ出力...
-
一行だけ読込
-
Fortranで1行飛ばして読み込む方法
おすすめ情報