いつもお世話になっております.環境はWindows XPのActiveperlです.
やりたいことは「下のディレクトリ(3つ)に含まれる同じファイル名のテキストを結合し,カレントディレクトリに出力する」ことです.具体的にはいかのようにしたいと思っています.
現在のディレクトリ/a/1.txt
a
b
c
現在のディレクトリ/b/1.txt
d
e
f
現在のディレクトリ/c/1.txt
g
h
i
現在のディレクトリ/1.txt
a
b
c
d
e
f
g
h
i
ここで私は以下のプログラムを作成しました.
use strict;
use warnings;
my $dirname1 = './a/';
my $dirname2 = './b/';
my $dirname3 = './c/';
opendir(DIR1, $dirname1) or die "$dirname1: $!";
while (my $dir1 = readdir(DIR1)) {
next unless (-f $dir1);
next unless ($dir1 =~ /\.txt$/);
opendir(DIR2, $dirname2) or die "$dirname2: $!";
while (my $dir2 = readdir(DIR2)) {
next unless (-f $dir2);
next unless ($dir2 =~ /\.txt$/);
opendir(DIR3, $dirname3) or die "$dirname3: $!";
while (my $dir3 = readdir(DIR3)) {
next unless (-f $dir3);
next unless ($dir3 =~ /\.txt$/);
if (($dir1 == $dir2) && ($dir2 == $dir3)){
open(FILE1, $dir1) or die "$dir1: $!";
my $line1 = <FILE1>;
close(FILE1);
open(FILE2, $dir2) or die "$dir2: $!";
my $line2 = <FILE2>;
close(FILE2);
open(FILE3, $dir3) or die "$dir3: $!";
my $line3 = <FILE3>;
close(FILE3);
my $joint_line = $line1.$line2.$line3;
open(NEWFILE, "> $dir1") or die "$dir1: $!";
print NEWFILE $joint_line;
close(NEWFILE);
}
}
}
}
closedir(DIR1);
closedir(DIR2);
closedir(DIR3);
ですが,以下のようなエラーが発生しています.
closedir() attempted on invalid dirhandle DIR2 at joint.pl line 51.
closedir() attempted on invalid dirhandle DIR3 at joint.pl line 52.
ディレクトリハンドルが使われているけれど閉じているか実際にはディレクトリハンドルでは無い時にこれらの警告が発行されるとこの警告がでるようですが,どのようにしたら解決できるのでしょうか.よろしくお願いします.
A 回答 (4件)
- 最新から表示
- 回答順に表示
No.4
- 回答日時:
そもそも、あるディレクトリにあるファイル名を取り出すのに
opendir/reeaddir/closedir を使うこともないと思います。
@files = grep { -f } glob("$dir/*.txt");
てな感じで一気にリストが取れるのではないかと。
sakusaker7様
ご回答ありがとうございます.
@files1 = grep { -f } glob("$dir1/*.txt");
@files2 = grep { -f } glob("$dir2/*.txt");
@files3 = grep { -f } glob("$dir3/*.txt");
で@filesに格納したあと,結合はどのようにするのでしょうか.
*.txtで同じ場合,結合とするのですが,ヒントをいただけないでしょうか.
No.3
- 回答日時:
ん~, なんか勘違いされてるような気が....
まず,
my $dir = './a/';
my %fcount;
opendir(DIR, $dir1);
for my $filename (readdir(DIR)) {
$fcount{$filename}++ if -f "$dir1$filename" && $filename =~ /\.txt$/;
}
closedir(DIR);
とやると, ハッシュ %fcount は ./a の中にあるテキストファイルのみ 1 という値を持ちます. なので, 同じことを他のディレクトリに対しても行えば, 各ファイル名に対して「何個のディレクトリの中にあるか」がわかります.
今の場合は「3個のディレクトリにある」ファイル名に対して処理をするわけですから, %fcount の値が 3 であるようなキーに対して処理すればいいということになります.
現状では readdir が 3重ループになってますが, これなら 3回ループするだけなので高速であることが期待できます.
Tacosan様
ご回答ありがとうございます.
以下のように組んでみたのですがうまくいきません.
use strict;
use warnings;
my $dir1 = './a/';
my $dir2 = './b/';
my $dir3 = './c/';
my %fcount;
opendir(DIR1, $dir1);
for my $filename1 (readdir(DIR1)) {
$fcount{$filename}++ if -f "$dir1/$filename" && $filename =~ /\.txt$/;
}
closedir(DIR1);
opendir(DIR2, $dir2);
for my $filename2 (readdir(DIR2)) {
$fcount{$filename}++ if -f "$dir2/$filename" && $filename =~ /\.txt$/;
}
closedir(DIR2);
opendir(DIR3, $dir3);
for my $filename3 (readdir(DIR3)) {
$fcount{$filename}++ if -f "$dir3/$filename" && $filename =~ /\.txt$/;
}
closedir(DIR);
if ($fcount == 3){
my $line = $filename1.$filename2.$filename3;
open(NEWFILE, "> ./out/$dir") or die "$dir: $!";
print NEWFILE $line;
close(NEWFILE);
}
間違っている点をご連絡ください.よろしくお願いします.
No.2
- 回答日時:
あれ? ディレクトリハンドルってブロックスコープなんだっけ....
とりあえず, もとのプログラムで closedir(DIR2) や closedir(DIR3) を適切な位置 (それぞれのディレクトリハンドルを opendir したブロックの最後) に移せば, エラーそのものは出ないと思う.... けど, それだけでは正しく動かないはず.
まずはじめに 3つのディレクトリから「共通のファイル名」を選んでおき, それらに対して改めてマージするというように書いた方が安全だと思う. 今のままでも (一部を修正すれば) 動くけど, 明らかに無駄.
Tacosan様
ご回答ありがとうございます.
それでは,入力ファイルと出力ファイル(入力名と出力名が同じため1つ)を作っておいて,それを参照してディレクトリから読み込んでマージがいいですし,早いんですね.明日早速試してみます.
No.1
- 回答日時:
opendir して中身を取り出したら、次のopendirをする前にclosedirする。
sakusaker7様
ご回答ありがとうございます.
> opendir して中身を取り出したら、次のopendirをする前にclosedirする。
とは以下のようなごとでしょうか.
use strict;
use warnings;
my $dirname1 = './1-5/';
my $dirname2 = './6-10/';
my $dirname3 = './11-12/';
opendir(DIR1, $dirname1) or die "$dirname1: $!";
while (my $dir1 = readdir(DIR1)) {
next unless (-f $dir1);
next unless ($dir1 =~ /\.txt$/);
open(FILE1, $dir1) or die "$dir1: $!";
my $line1 = <FILE1>;
close(FILE1);
closedir(DIR1); #←ここに挿入
opendir(DIR2, $dirname2) or die "$dirname2: $!";
while (my $dir2 = readdir(DIR2)) {
next unless (-f $dir2);
next unless ($dir2 =~ /\.txt$/);
open(FILE2, $dir2) or die "$dir2: $!";
my $line2 = <FILE2>;
close(FILE2);
closedir(DIR2); #←ここに挿入
opendir(DIR3, $dirname3) or die "$dirname3: $!";
while (my $dir3 = readdir(DIR3)) {
next unless (-f $dir3);
next unless ($dir3 =~ /\.txt$/);
open(FILE3, $dir3) or die "$dir3: $!";
my $line3 = <FILE3>;
close(FILE3);
closedir(DIR3); #←ここに挿入
if (($dir1 eq $dir2) && ($dir2 eq $dir3)){
my $joint_line = $line1.$line2.$line3;
open(NEWFILE, "> $dir1") or die "$dir1: $!";
print NEWFILE $joint_line;
close(NEWFILE);
}
}
}
}
そうしますと,エラーは出ないのですが出力されません.
なぜなのでしょうか.よろしくお願いします.{}の位置が違うのでしょうか.
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- Word(ワード) ネットの文章をワードに貼り付けるとき、幅を広げる方法 6 2022/05/30 11:04
- 工学 過渡現象 RL回路で 回路方程式 Ri+L(di/dt)=E 定常解 is=E/R 過渡解 Ri+L 1 2022/06/08 21:47
- 楽器・演奏 RolandのJuno di で、デュアルモードで作った音をスプリットモードで使用することはできない 1 2023/08/10 17:57
- Visual Basic(VBA) ExcelVBAに関する質問 3 2023/02/17 10:47
- 数学 『iの微分』 7 2023/02/06 19:45
- オープンソース イラストのDLサイト 1 2023/05/11 17:33
- イタリア語 イタリア語が得意な方に質問なんですが、椿姫のアルフレードの歌、7音節詩行ですが、この音節分けをして欲 1 2022/05/17 17:12
- デジタルカメラ 動画撮影に使うレンズ。どちらのレンズがいいか悩んでいます 1 2023/01/02 18:21
- モデル 外国人のモデルさんについて 2 2022/09/25 13:29
- 一眼レフカメラ canonのeosシリーズ使ってます。 広角レンズをレンタルしようと考えています。 canon純正 5 2023/02/20 23:33
関連するカテゴリからQ&Aを探す
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
パスから最後のディレクトリだ...
-
dos変数の%~dp0は powershellで...
-
複数ファイルの読み込みについて
-
vba dir の相対パス
-
batファイルでrenameができませ...
-
Windowsで複数のファイルを同じ...
-
ファイルの削除について
-
LinuxのC言語で、ファイル名の...
-
readdir()で得られるファイル・...
-
find関数が1階層(カレントディ...
-
fopenでディレクトリ内の全ファ...
-
バッチファイルの作り方(CSV→...
-
ReadLineでの読み出し行を指定する
-
awkスクリプトでダブルクォーテ...
-
教えて!perlから.exeファイル...
-
MySQLに画像を格納してperlで取...
-
ExcelをCSV書き出す場合のシー...
-
DOSコマンドで、標準出力を出力...
-
perlを用いた特定文字列間の抽...
-
perlでの三次元配列の作り方
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
batファイルでrenameができませ...
-
readdir()で得られるファイル・...
-
ディレクトリ名を取得したい
-
パスから最後のディレクトリだ...
-
Windowsで複数のファイルを同じ...
-
C言語でファイル名を取得
-
FindFirstFileとFindNextFileで...
-
Perlで フォルダ内の全て...
-
エラー 'dir.h' : No such fi...
-
vba dir の相対パス
-
一定時間が経過したフォルダの削除
-
テキストファイルの結合
-
LinuxのC言語で、ファイル名の...
-
chdirがうまくできない
-
複数のCSVファイルを一つのCSV...
-
ディレクトリの判別
-
空白を含むディレクトリにある...
-
Perl 特定のフォルダ以外削除
-
正規表現で、特定のファイル名...
-
dos変数の%~dp0は powershellで...
おすすめ情報