
Perl で特定のフォルダ以外を削除したいのですが
普通はフォルダを指定して削除するところを
rmdir "log/delete";
上記のように削除させますが
ディレクトリ構造↓
log----1/
-------2/
-------3/
-------4/
-------5/
-------delete/
-------log.txt
上記のlog.txtの中身↓
1
2
3
4
5
-------------------
のように連番が振ってあり
その連番と同じフォルダがなければ削除
と今回の場合
deleteフォルダがないので
それを削除させたいのですが、
rmdir "log/delete";
↑これではなく
1,2,3,4,5を残し、それ以外のフォルダを削除
という指定にしたいのですが
どのようにすればいいでしょうか?
No.6ベストアンサー
- 回答日時:
さすがに #1 に書いたようなスクリプトだと保守性が悪すぎるので, 最後の
remove_tree grep { -d; } map { "$parent_dir/$_"; } grep { my $f = $_; $f ne "." && $f ne ".." && ! grep { $_ eq $f; } @preserve_dirs; } readdir DH;
は
for my $f (readdir DH) {
next if $f eq '.';
next if $f eq '..';
next if grep { $_ eq $f; } @preserve_dirs;
my $d = "$parent_dir/$f"; #ここも File::Spec::catfile を使う方が安全?
remove_tree $d if -d $d;
}
くらいのループにすべきですけどね. あれは
その気になればこのくらい圧縮できる
という (無意味かつ悪い) 実例ですから.
なるほどなるほど
一度フォルダ内のリストを取得させ
そこから「.」「..」をまずはぶき
フォルダ内=配列のものをgrepさせ
最後にリストに内ものを削除するのですね!
File::Spec::catfil
↑初めて見ました
↓これですね。。
http://search.cpan.org/~xsawyerx/PathTools-3.74/ …
おおよそ理解できてきたので、↑のモジュールは自分と勉強して
使えるようにしたいと思います!
ありがとうございました!!
No.5
- 回答日時:
正直にいわせてもらうと, grep や map を理解していないんじゃないかなと思う.
あと「前回の処理だと1つのファイルしか削除されなかった」はなにかを勘違いしてるんじゃないだろうか. 少なくとも手元ではちゃんと「log.txt に書かれていないディレクトリ」を一度で全部消してる.
たしかにそうでした。
ただ、上手く説明できませんが・・・
@preserve_dirs
この子が対象だということですね
use File::Path;
↓
use File::Path 'remove_tree';
これにするだけで解決でした。
ここまでの仮定で、余計なForを入れてるからおかしなことになっていたのですね。
No.4
- 回答日時:
え.... 問題ないというか, ほぼ「問題しかない」んですが....
何をやっているか, 理解できていますか? 自分の言葉で説明できますか?
なんですって・・・;;
まだまだ理解できてませんねorz
my $parent_dir = "log";
my @preserve_dirs;
open FH, "$parent_dir/log.txt";
chomp(@preserve_dirs = <FH>);
#▲ここで、log.txtの中身を取得
my $dir_serch="./log/";
my @Kosu;
opendir(DIR, "$dir_serch");
my @file = readdir(DIR);
foreach (@file) {
push @Kosu , "$_\n";
}
closedir(DIR);
#▲無理やりではありますが、フォルダ内の名前を取り出し
#▼下のループの最後まで $#Kousu = [.][..]も含んだままなので
#ループ処理が多くなってますが。。
for(my $fd=0;$fd<=$#Kosu;$fd++){
opendir DH, $parent_dir;
remove_tree grep { -d; }
map { "$parent_dir/$_"; }
grep { my $f = $_; $f ne "." && $f ne ".." &&
! grep { $_ eq $f; } @preserve_dirs; } readdir DH;
closedir DH;
}
#質問には含めていませんでしたが、
#前回の処理だと1つのファイルしか削除されなかったので、
#複数消したかったため、ループ処理を加えておりました・・・
No.3
- 回答日時:
動作はそれで OK のはず. ただし
http://perldoc.perl.org/File/Path.html
によると rmtree は古い形式 (超意訳) なので, そこは remove_tree の方が安全かと.
grep や map は
・grep: 配列から指定した条件を満たす要素を取り出し配列として返す
・map: 配列の各要素に対して処理した結果を配列として返す
という動作.
それからついでに
chomp(@preserve_dirs = <FH>);
を
%preserve_dirs = ('.' => 1, '..' => 1, map { chomp; $_ => 1; } <FH>);
のようにハッシュにしておけばあとの
grep { my $f = $_; $f ne "." && $f ne ".." && ! grep { $_ eq $f; } @preserve_dirs; } readdir DH
を
grep { ! $preserve_dirs{$_}; } readdir DH
と短縮できることに一晩寝て気付いた.
と書いておくけど, 本当に実用とするのであればこんなに grep や map をばんばか使うんじゃなくっててきせつなループにすべきだと思う.
なるほど!
ただ、ハッシュの仕組みが未だに理解できていないので、今は使わないようにしておきます・・・
ループ処理をヒントに
最終的に
use strict;
use warnings;
use File::Path 'remove_tree';
my $parent_dir = "log";
my @preserve_dirs;
open FH, "$parent_dir/log.txt";
chomp(@preserve_dirs = <FH>);
my $dir_serch="./log/";
my @Kosu;
opendir(DIR, "$dir_serch");
my @file = readdir(DIR);
foreach (@file) {
push @Kosu , "$_\n";
}
closedir(DIR);
for(my $fd=0;$fd<=$#Kosu;$fd++){
my $Ko = $Kosu[$fd];
opendir DH, $parent_dir;
remove_tree grep { -d; }
map { "$parent_dir/$_"; }
grep { my $f = $_; $f ne "." && $f ne ".." &&
! grep { $_ eq $f; } @preserve_dirs; } readdir DH;
closedir DH;
}
close FH;
このようになりましたが、問題ないでしょうか・・・?
No.2
- 回答日時:
直すのはもちろん直せるんだけど, どのようなことをしようとしているか理解できているのですか?
ある程度は理解しているつもりではありますが・・・
自信はありません・・・
$parent_dir = "log";
open FH, "$parent_dir/log.txt";
chomp(@preserve_dirs = <FH>);
close FH;
これはログテキスト内の列を取得し、配列へ
でもここがわからないです
remove_tree grep { -d; }
↑これはわからない
フォルダを削除だと思うのですが、初めて見ました・・・→「remove_tree」
map { "$parent_dir/$_"; }
↑これもわからない
?log/ ←内のフォルダのリスト化?
grep { my $f = $_; $f ne "." && $f ne ".." && ! grep { $_ eq $f; } @preserve_dirs; }
おそらくこれする前を、print表示すると
----------------------------------------
.
..
1
2
3
4
5
delete
----------------------------------------
↓これを
----------------------------------------
1
2
3
4
5
----------------------------------------
[.][..]はフォルダーパス取得したときに付与されている?のと
! grep { $_ eq $f; } ログファイル内と、フォルダリストがイコールでないやつ
ということでしょうか?
初めてみた→「remove_tree」
でググっているうちに
↓にたどり着き
use File::Path; → use File::Path 'rmtree';
remove_tree → rmtree
に変更させると実行はできたのですが、
正しいでしょうか?
No.1
- 回答日時:
use File::Path;
$parent_dir = "log";
open FH, "$parent_dir/log.txt";
chomp(@preserve_dirs = <FH>);
close FH;
opendir DH, $parent_dir;
remove_tree grep { -d; } map { "$parent_dir/$_"; } grep { my $f = $_; $f ne "." && $f ne ".." && ! grep { $_ eq $f; } @preserve_dirs; } readdir DH;
closedir DH;
みたいな感じ?
ソースご掲示ありがとうございます。
実行してみたのですが
下記のようなエラーがでたのですが、
Use of my $_ is experimental at test.pl line 7.
Use of my $_ is experimental at test.pl line 7.
syntax error at test.pl line 7, near "remove_tree
grep"
syntax error at test.pl line 7, near "; }"
Execution of test.pl aborted due to compilation er
rors.
どういうことでしょうか・・?
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- ノートパソコン pcでフォルダをDeleteで削除しようとしたのですが、別のフォルダを削除する所だったので急いでキャ 6 2022/12/05 16:56
- Excel(エクセル) 2つのマクロを連続して動かしたい 3 2022/09/20 23:46
- Outlook(アウトルック) すべての新着メールが「受診フォルダ」に入らない。 2 2023/02/24 20:28
- Visual Basic(VBA) エクセルのマクロについて教えてください。 2 2023/07/06 17:46
- Visual Basic(VBA) エクセルのマクロについて教えてください マクロを実行すると メッセージボックスが表示されて okをク 4 2023/07/05 19:32
- Excel(エクセル) マクロのコードを、少しでも削って短くしたい 3 2022/08/30 07:46
- Visual Basic(VBA) フォルダの場所を可変にしたいです(マクロ) 4 2023/05/11 10:00
- その他(クラウドサービス・オンラインストレージ) OneDriveで特定のフォルダ(写真だと、スクリーンショット)の内容だけをバックアップしない方法を 2 2022/05/20 01:44
- Visual Basic(VBA) エクセルのマクロについて教えてください。 3 2023/07/01 10:35
- サーバー windowsサーバの権限設定、フォルダ削除できないアカウントを作りたい 1 2023/04/07 09:58
関連するカテゴリからQ&Aを探す
おすすめ情報
- ・漫画をレンタルでお得に読める!
- ・「それ、メッセージ花火でわざわざ伝えること?」
- ・ゆるやかでぃべーと すべての高校生はアルバイトをするべきだ。
- ・【お題】甲子園での思い出の残し方
- ・【お題】動物のキャッチフレーズ
- ・人生で一番思い出に残ってる靴
- ・これ何て呼びますか Part2
- ・スタッフと宿泊客が全員斜め上を行くホテルのレビュー
- ・あなたが好きな本屋さんを教えてください
- ・かっこよく答えてください!!
- ・一回も披露したことのない豆知識
- ・ショボ短歌会
- ・いちばん失敗した人決定戦
- ・性格悪い人が優勝
- ・最速怪談選手権
- ・限定しりとり
- ・性格いい人が優勝
- ・これ何て呼びますか
- ・チョコミントアイス
- ・単二電池
- ・初めて自分の家と他人の家が違う、と意識した時
- ・「これはヤバかったな」という遅刻エピソード
- ・ゴリラ向け動画サイト「ウホウホ動画」にありがちなこと
- ・泣きながら食べたご飯の思い出
- ・一番好きなみそ汁の具材は?
- ・人生で一番お金がなかったとき
- ・カラオケの鉄板ソング
- ・自分用のお土産
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
vba dir の相対パス
-
正規表現で、特定のファイル名...
-
FindFirstFileとFindNextFileで...
-
テキストファイルの結合
-
readdir()で得られるファイル・...
-
batファイルでrenameができませ...
-
ディレクトリの判別
-
ディレクトリのファイル作成を...
-
Perl 特定のフォルダ以外削除
-
perl(CGI)から作成したディレク...
-
LinuxのC言語で、ファイル名の...
-
エラー 'dir.h' : No such fi...
-
ディレクトリ内の全ファイルを...
-
空白を含むディレクトリにある...
-
C言語でファイル名を取得
-
Windowsで複数のファイルを同じ...
-
Perlで フォルダ内の全て...
-
ExcelをCSV書き出す場合のシー...
-
VBAで巨大なファイルの途中から...
-
ReadLineでの読み出し行を指定する
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
batファイルでrenameができませ...
-
Windowsで複数のファイルを同じ...
-
readdir()で得られるファイル・...
-
C言語でファイル名を取得
-
ディレクトリ名を取得したい
-
FindFirstFileとFindNextFileで...
-
dos変数の%~dp0は powershellで...
-
パスから最後のディレクトリだ...
-
vba dir の相対パス
-
サーバーにある特定の拡張子フ...
-
makefileでファイルをコピー(...
-
Perlで フォルダ内の全て...
-
chdirがうまくできない
-
ディレクトリ内の全ファイルを...
-
空白を含むディレクトリにある...
-
ディレクトリの判別
-
Net::FTPを使いファイル一覧の...
-
Windows漢字フォルダ名の扱い(...
-
エラー 'dir.h' : No such fi...
-
スクロールバーを左側に、又は...
おすすめ情報