指定されたフォルダ以下のゴミ掃除
Posted feedbacks - Flatten
Nested Hiddenエラーハンドリングは省略してます。
1 2 3 4 5 6 7 | import os
def remove_backup(root_path):
for w in os.walk(root_path):
for f in w[2]:
if f.endswith('~'):
os.remove('%s/%s' % (w[0], f))
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | import java.io.File;
import java.io.FileFilter;
public class FileCleaner {
private File rootDir;
public FileCleaner(String rootDir) {
this(new File(rootDir));
}
public FileCleaner(File rootDir) {
this.rootDir = rootDir;
}
public void deleteFilesBySuffix(String suffix) {
FileFilter filter = new FileFilter() {
public boolean accept(File pathname) {
return pathname.isFile() && pathname.getName().endsWith("~");
}
};
deleteTargetFiles(rootDir, filter);
}
private void deleteTargetFiles(File dir, FileFilter filter) {
File[] fileList = dir.listFiles();
for (int i=0; i<fileList.length; i++) {
File file = fileList[i];
if (file.isDirectory()) {
deleteTargetFiles(file, filter);
} else {
if (filter.accept(file)) {
file.delete();
System.out.println(file + " を削除しました。");
}
}
}
}
public static void main(String[] args) {
if (args.length == 0) {
System.err.println("ディレクトリを指定してください。");
return;
}
new FileCleaner(args[0]).deleteFilesBySuffix("~");
}
}
|
なんとなくCで
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | #include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <dirent.h>
#include <unistd.h>
void remove_backup(const char *dn){
DIR *dp;
struct dirent *de;
char path[PATH_MAX];
struct stat st;
if(!(dp = opendir(dn))) return;
while((de = readdir(dp))){
if(!strcmp(de->d_name, ".") || !strcmp(de->d_name, "..")) continue;
snprintf(path, PATH_MAX, "%s/%s", dn, de->d_name);
stat(path, &st);
if(S_ISREG(st.st_mode) && de->d_name[strlen(de->d_name) - 1] == '~')
unlink(path);
else if(S_ISDIR(st.st_mode))
remove_backup(path);
}
}
|
1 2 3 4 5 6 7 8 9 10 11 12 13 | class Dir
def delete_rec(pat)
self.each do |e|
next if e == '.' or e == '..'
p = self.path + '/' + e
File.delete(p) if pat =~ e and File.writable?(p)
Dir.open(p).delete_rec(pat).close if File.directory?(p)
end
self
end
end
Dir.open(ARGV[0]).delete_rec(/~$/).close
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | <?php
remove_file('.', '~$');
function remove_file($dir, $regex){
$d = dir($dir);
while (($file = $d->read()) !== false) {
if ($file == '.' || $file == '..') continue;
$path = $d->path . "/$file";
if (is_dir($path)){
remove_file($path, $regex);
}else if (preg_match("/$regex/", $path)){
echo "delete $path\n";
unlink($path);
}
}
$d->close();
}
?>
|
1 | perl -MFile::Find -e "find(sub {/.*~$/ && unlink \$File::Find::name;}, '.');"
|
1 2 3 4 | (use file.util)
(define (remove-backup dir)
(directory-fold "." (lambda (path seed) (and (#/~$/ path) (sys-unlink path))) #f))
(define (main args) (for-each remove-backup (cdr args)) 0)
|
うわ、違うバージョンを貼り付けてしまった。 3行目、s/print/sys-unlink/ です。
1 2 3 4 5 6 7 | require 'find'
Find.find(".") do |fn|
if File.file?(fn) && ?~ == fn[-1]
File.unlink(fn)
end
end
|
1 2 3 | Dir.glob('**/*~') do |path|
File.unlink(path)
end
|
古のバッチファイルが今こそ火を噴く! 調子に乗りましたすいません。
1 | for /D /R %%d in (*~) do (echo "%%d")
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | import os.path
import os
from optparse import OptionParser
parser = OptionParser(usage="%prog <folder to start>", description='remove files end with "~" recursively.')
(opsions, args) = parser.parse_args()
if len(args) != 1:
parser.error("need argument <folder to start>")
path = os.path.abspath(args[0])
def remove_them(parser, dirname, names):
for name in names:
t = os.path.join(dirname, name)
if name.endswith('~'):
try:
os.remove(t)
except e:
print e, " skip to remove: ", t
os.path.walk(path, remove_them, parser)
|
1 2 3 4 5 6 | fun! DeleteBackupFiles(dir)
for v in split(globpath(a:dir, "*~"), "\n")
call delete(v)
endfor
endfun
call DeleteBackupFiles("/tmp")
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | using System;
using System.IO;
namespace Doukaku.CS
{
public class DelNyoro
{
static void Main(string[] args)
{
foreach(string dir in args)
{
if (Directory.Exists(dir))
{
foreach (string nyoroFile in Directory.GetFiles(dir, "*~", SearchOption.AllDirectories))
File.Delete(nyoroFile);
}
else
Console.WriteLine(string.Format("Directory %s is not exists.", dir));
}
}
}
}
|
1 | del /s *~
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | import Control.Monad
import System
import System.Directory
main :: IO ()
main = do [root] <- getArgs
removeBackup root
removeBackup :: FilePath -> IO ()
removeBackup dir
= getDirectoryContents dir >>= mapM_ (removeIfBackupFile dir)
where
removeIfBackupFile :: FilePath -> FilePath -> IO ()
removeIfBackupFile _ "." = return ()
removeIfBackupFile _ ".." = return ()
removeIfBackupFile dir file
= do let path = dir ++ "/" ++ file
isDir <- doesDirectoryExist path
if last path == '~' then
if isDir then
removeDirectoryRecursive path
else
removeFile path
else
when isDir $ removeBackup path
|
それはどうかな。
[5:51PM shyouhei]% mkdir tmp~
[5:51PM shyouhei]% ruby -e"
dquote> Dir.glob('**/*~') do |path|
dquote> File.unlink(path)
dquote> end"
-e:3:in `unlink': Is a directory - tmp~ (Errno::EISDIR)
from -e:3
from -e:2:in `glob'
from -e:2
zsh: exit 1 ruby -e" Dir.glob('**/*~') do |path| File.unlink(path) end "
まぁ、わざわざオブジェクト思想にこだわる必要もないか。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | import java.io.File;
public class DelteFile {
public static void main(String[] args) throws Exception {
for (int i = 0; i < args.length; i++) delete(new File(args[i]));
}
private static void delete(File f) throws Exception {
if (f.isDirectory()) {
for (int i = 0; i < f.listFiles().length; i++) {
delete(f.listFiles()[i]);
}
} else {
if (f.getName().endsWith("~")) {
if (!f.delete()) {
throw new Exception("何らかの原因で削除できず");
}
}
}
}
}
|
1 | main(){system("find . -type f -name '*~' | xargs rm");}
|
1 2 3 4 5 6 7 8 9 10 11 12 13 | #! /bin/bash
shopt -s dotglob #for dotfile
function rm_g(){
local file proc_dir=$1
for file in ${proc_dir}/*; do
[ ${file:(-1):1} == '~' ] && rm $file
[ -d $file ] && rm_g $file
done
}
rm_g ~/tmp
|
erl -noshell -eval 'delbackup:delbackup("."), halt().'
のように実行します.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | -module(delbackup).
-export([delbackup/1]).
delbackup(RootPath) ->
check_dir(RootPath).
check_dir(Path) ->
case file:list_dir(Path) of
{ok, FileList} ->
check_file(Path, FileList);
{error, Reason} ->
io:format("Error. ~s (~p)~n", [Path, Reason])
end.
check_file(Path, [File|RestFile]) ->
FilePath = Path ++ "/" ++ File,
io:format("~s~n", [FilePath]),
IsDir = filelib:is_dir(FilePath),
IsFile = filelib:is_file(FilePath),
case {IsDir, IsFile} of
{true, _} ->
check_dir(FilePath);
{_, true} ->
check_backup(FilePath);
_Other ->
ok
end,
check_file(Path, RestFile);
check_file(_Path, []) ->
ok.
check_backup(FilePath) ->
case regexp:match(FilePath, "~$") of
{match, _, _} ->
file:delete(FilePath),
io:format("delete ~s~n", [FilePath]);
_Else ->
ok
end.
|
1 | for /D /R %%d in (*~) do (rd "%%d" /s /q)
|
find -name '*~' -exec rm -f \{\} \;
1 | find . -name '*~' -exec /bin/rm {} \;
|
1 | find $dir -type f -name \*~ -print0 | xargs -0 rm -f
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | # dma.pl
$ARGV[0] or die "Usage: $0 DIRECTORY...\n";
foreach my $dir (@ARGV) {
dfswalk($dir, sub {
my $path = shift;
if ($path =~ /~$/ and -f $path) {
unlink($path) or warn("$path: $!\n");
}
});
};
sub dfswalk
{
my ($dir, $fn) = @_;
unless (opendir(D, $dir)) {
warn "$dir: $!\n";
return;
}
foreach my $name (readdir(D)) {
next if ($name eq '.' or $name eq '..');
my $path = sprintf("%s/%s", $dir, $name);
&$fn($path);
if (-d $path) {
dfswalk($path, $fn);
}
}
closedir(D);
}
|
1 2 | #!/bin/sh
find . -name '*~' -print | xargs rm
|
1 | BEGIN{system("find . -type f -name '*~' | xargs rm")}
|
1 2 3 4 5 6 7 8 9 10 11 | using System;
using System.IO;
class Program
{
static void Main()
{
string dir = @"C:\test";
foreach (string s in Directory.GetFiles(dir, "*~", SearchOption.AllDirectories))
File.Delete(s);
}
}
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | open System;;
open System.IO;;
open Array;;
open Printf;;
let del path =
let dirFiles = Directory.GetFiles(path, "*~", SearchOption.AllDirectories) in
iter File.Delete dirFiles;;
if length Sys.argv = 2
then
del Sys.argv.(1)
else
();;
|
Squeak Smalltalk で手続き的に。
1 2 3 4 5 6 7 8 9 10 | | startDir queue |
startDir := FileDirectory default.
queue := OrderedCollection with: startDir.
[queue notEmpty] whileTrue: [
| dir subDirs fileNames |
dir := queue removeFirst.
subDirs := dir directoryNames collect: [:dirName | dir directoryNamed: dirName].
queue addAll: subDirs.
fileNames := dir fileNames select: [:fileName | fileName endsWith: '~'].
fileNames do: [:fileName | dir deleteFileNamed: fileName]]
|
1 | ls $args[0] -include *~ -recurse | rm
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 | #include <windows.h>
#include <string>
void traverse(const std::string& parent, void (*func)(const std::string& path))
{
WIN32_FIND_DATA wfd;
HANDLE h = ::FindFirstFile((parent + "\\*").c_str(), &wfd);
if (h == INVALID_HANDLE_VALUE)
{
return;
}
do
{
const std::string name = wfd.cFileName;
if (name == "." || name == "..")
{
continue;
}
const std::string child = parent + "\\" + name;
if (wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
{
traverse(child, func);
}
else // file
{
func(child);
}
}
while (::FindNextFile(h, &wfd));
::FindClose(h);
}
void delete_garbage(const std::string& path)
{
if (!path.empty() && path[path.size() - 1] == '~')
{
::DeleteFile(path.c_str());
}
}
int main()
{
traverse("foo", &delete_garbage);
}
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | --- orig.cpp Fri Jul 13 01:13:55 2007
+++ main.cpp Fri Jul 13 01:15:08 2007
@@ -45,7 +45,10 @@
}
}
-int main()
+int main(int argc, char* argv[])
{
- traverse("foo", &delete_garbage);
+ if (argc == 2)
+ {
+ traverse(argv[1], &delete_garbage);
+ }
}
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | require "pathname"
class Pathname
def scatter( upper, upper_h = 0 )
raise "`#{ self }' is not directory, ;-<" unless self.directory?
(10**upper).times {|i|
r = rand( 2 + ( upper_h > 0 ? 1 : 0 ) )
case r
when 0, 1
nfile = self + ( "%0#{ upper }d#{ r == 0 ? "" : "~" }" % i)
nfile.open( "w" ) {|fd|
fd.write( File.open( "/dev/random" ) {|rdev| rdev.read( 8 ) } )
} unless nfile.exist? and nfile.directory?
when 2
ndir = self + ("%0#{ upper }d" % i)
ndir.mkdir unless ndir.exist?
ndir.scatter( upper, upper_h - 1 ) if ndir.directory?
end
}
self
end
def cleaner
raise "`#{ self }' is #{ self.ftype }, :-)" unless self.directory?
self.children.each {|epath|
if epath.file?
epath.delete if /~\Z/ =~ epath
elsif epath.directory?
epath.cleaner
end
}
end
end
Pathname.new( "temp" ).scatter( 2, 2 ).cleaner
|
1 2 3 4 5 6 | (defun remove-backup ()
(let ((str (or (pathname-type path) (pathname-name path))))
(when (char= #\~ (char str (1- (length str))))
(delete-file path))))
(fad:walk-directory ディレクトリ名 #'remove-backup)
|
1 2 3 4 5 6 7 8 9 10 | (require 'cl)
(defun directory-files-recursively (dir &optional match-regexp nosort)
(loop for f in (directory-files dir t "." nosort)
when (and (not (string-match "/\\.+$" f)) (file-directory-p f))
appending (directory-files-recursively
f match-regexp nosort)
when (string-match match-regexp f) collect f))
(defun delete-backup-files-recursively (dir)
(mapcar #'delete-file (directory-files-recursively dir "~$" t)))
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | import java.io._
object FileUtil {
def removeFilesBySuffix(d:String, s:String):Unit = {
removeFilesBySuffix(new File(d), s)
}
def removeFilesBySuffix(d:File, s:String):Unit = {
d.list.foreach(f => {
val c = new File(d, f)
if(c.isDirectory) removeFilesBySuffix(c, s)
else if(f.endsWith(s)) c.delete
})
}
}
|
ファイルを弄くるなんて、普段やらないのでこういう書き方で良いのかよくわかんね。
1 2 3 4 5 6 7 8 9 10 11 12 | def file_delete (path="")
Dir.foreach(path) do |file|
filepath = path + '/' + file
# ディレクトリで、かつ . か .. 以外だったら再帰的にメソッドを呼ぶ
if File.ftype(filepath) == 'directory' && file != '.' && file != '..'
file_delete(filepath)
end
File.delete(filepath) if file =~ /~$/
end
end
file_delete ("/hoge/file/path")
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | function dir_walk(path, f)
if lfs.attributes(path, "mode") == "directory" then
for file in lfs.dir(path) do
if not(file == "." or file == "..") then
dir_walk(path .. "/" .. file, f)
end
end
else
f(path)
end
end
dir_walk(arg[1], function(path)
if string.find(path, "~$") then
print(path)
os.remove(path)
end
end)
|
1 2 3 4 5 6 7 8 9 | remove.backup <- function(root = "."){
list <- dir(root, all.files=TRUE)
list <- list[-grep("^\\.$|^\\.\\.$", list)]
list <- file.info(file.path(root, list))
rmfiles <- grep("~$", rownames(list[which(list$isdir==FALSE),]), value=TRUE)
dirs <- rownames(list[which(list$isdir==TRUE),])
file.remove(rmfiles)
for(d in dirs) remove.backup(d)
}
|
GNU Prologです。 notも無いなんて…。 $ gprolog --entry-goal '[del],main,halt' で音もなく静かに実行。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | del_tilda(D):-del_tilda([],[D]).
not(P):-P,!,fail.
not(_).
del_tilda(_,[]).
del_tilda(D,[L|Ls]):-(D=[]->L1=L;atom_list_concat([D,'/',L],L1)),
(file_property(L1,type(directory)),
not(member(L,['..','.']))
-> directory_files(L1,L2),del_tilda(L1,L2),del_tilda(D,Ls)
; atom_chars(L,C),last(C,'~'),delete_file(L1),del_tilda(D,Ls)),!.
del_tilda(D,[_|Ls]):-del_tilda(D,Ls).
atom_list_concat([A],A).
atom_list_concat([A|As],B):-atom_list_concat(As,Bs),atom_concat(A,Bs,B).
main:-del_tilda('test').
|
1 2 3 4 5 | function cleanup(d){
for (f : walkDirectory(d)){
if (!f.directory && f.name.endsWith("~")) delete(f)
}
}
|
Myを使えば楽ちん
1 2 3 4 5 6 7 | Public Sub RemoveFile(ByVal directory As String)
For Each file As String In My.Computer.FileSystem.GetFiles(directory, FileIO.SearchOption.SearchAllSubDirectories, "*~")
My.Computer.FileSystem.DeleteFile(file)
Next
End Sub
|
1 2 3 4 5 6 7 8 9 | // Run as *.js or *.hta //<script language="jscript">
with(new ActiveXObject("Scripting.FileSystemObject")) (function(fold, spec){
for(var cf = new Enumerator(fold.SubFolders); !cf.atEnd(); cf.moveNext())
arguments.callee(cf.item(), spec);
try { DeleteFile(fold.Path +"\\"+ spec) } catch(e){}
})(GetFolder(
this.WSH ? (WSH.Arguments.Length ? WSH.Arguments(0) : ".\\") : prompt("", ".\\")
), "*~");
//</script>
|
setCurrentDirectory を使ってパスの扱いを単純化
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | import System.Directory
import System.Environment
main :: IO ()
main = getArgs >>= mapM_ cleaning
cleaning :: FilePath -> IO ()
cleaning = (>> removeBackupFiles) . setCurrentDirectory
removeBackupFiles :: IO ()
removeBackupFiles = getDirectoryContents "." >>= mapM_ rmbk . drop 2
rmbk :: FilePath -> IO ()
rmbk path
= do { dir <- doesDirectoryExist path
; let backup = '~'== last path
; if dir
then if backup then removeDirectoryRecursive path else cleaning path
else if backup then removeFile path else return ()
}
|
特に工夫なし。
1 2 3 4 5 6 7 8 9 | def clean_directory(file) {
if(file.isFile() && file.name.endsWith("~")) {
file.delete()
} else if (file.isDirectory()) {
file.listFiles().each { f ->
clean_directory(f)
}
}
}
|
1 2 3 4 5 6 7 8 9 10 | file_delete := method(path,
dir := Directory clone setPath(path)
dir files foreach(f,
if(f name endsWithSeq("~"),
f remove
)
)
)
file_delete("/foo/bar")
|
-type f つけたほうが良いかもしれませんね。
ごめんなさいバグがありました。 ディレクトリを降りていったあとにカレントディレクトリを もとへ戻していなかった。こちらが正しいはずのコード です。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | import System.Directory
import System.Environment
main :: IO ()
main = getArgs >>= mapM_ cleaning
cleaning :: FilePath -> IO ()
cleaning = (>> removeBackupFiles) . setCurrentDirectory
removeBackupFiles :: IO ()
removeBackupFiles
= do { cwd <- getCurrentDirectory
; getDirectoryContents "." >>= mapM_ (rmbk cwd) . drop 2
}
rmbk :: FilePath -> FilePath -> IO ()
rmbk cwd path
= do { dir <- doesDirectoryExist path
; let backup = '~'== last path
; if dir
then if backup
then removeDirectoryRecursive path
else cleaning path >> setCurrentDirectory cwd
else if backup
then removeFile path
else return ()
}
|
1 | dir * -recurse -include *~ | rm
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 | //ソースファイルのエンコーディングはUTF-8にしてください
//コンパイルオプション:-std=gnu99 -fobjc-exceptions
#import <Foundation/Foundation.h>
#define WithUTF8Format(a, ...) [NSString stringWithFormat:[NSString stringWithUTF8String:(a)], __VA_ARGS__]
#define JLog(...) [(NSFileHandle*)[NSFileHandle fileHandleWithStandardError] \
writeData:[[NSString stringWithFormat:__VA_ARGS__] \
dataUsingEncoding:NSUTF8StringEncoding]];
BOOL deleteGarbage( NSString* folder ) {
BOOL result = YES;
NSAutoreleasePool* pool1 = [[NSAutoreleasePool alloc] init];
JLog( WithUTF8Format( "フォルダの中を検索します: %@\n", folder ) );
@try {
NSFileManager* manager = [NSFileManager defaultManager];
NSDictionary* folderAttributes = [manager fileAttributesAtPath:folder traverseLink:NO];
if ( folderAttributes == nil )
@throw WithUTF8Format( "フォルダの属性を取得できませんでした: %@\n", folder );
if ( [[folderAttributes fileType] isEqualToString:NSFileTypeSymbolicLink] )
@throw WithUTF8Format( "フォルダではなくシンボリックリンクです: %@\n", folder );
else if ( ![[folderAttributes fileType] isEqualToString:NSFileTypeDirectory] )
@throw WithUTF8Format( "フォルダではなくファイルです: %@\n", folder );
NSArray* paths = [manager directoryContentsAtPath:folder];
if ( paths == nil )
@throw WithUTF8Format( "フォルダの内容を取得できませんでした: %@\n", folder );
for ( int i = 0; i < [paths count] && result; i++ ) {
NSAutoreleasePool* pool2 = [[NSAutoreleasePool alloc] init];
@try {
NSString* path = [folder stringByAppendingPathComponent:[paths objectAtIndex:i]];
BOOL isDirectory;
if ( ![manager fileExistsAtPath:path isDirectory:&isDirectory] )
@throw WithUTF8Format( "ファイルまたはフォルダが存在しません: %@\n", path );
if ( isDirectory )
result = deleteGarbage( path );
else if ( [path hasSuffix:@"~"] ) {
if ( ![manager removeFileAtPath:path handler:nil] )
@throw WithUTF8Format( "ファイルを削除できませんでした: %@\n", path );
JLog( WithUTF8Format( "ファイルを削除しました: %@\n", path ) );
}
} @finally {
[pool2 release];
}
}
} @catch ( NSString* error ) {
JLog( error );
result = NO;
}
[pool1 release];
return result;
}
int main( int argc, const char** argv ) {
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
deleteGarbage( @"./Trash" );
[pool release];
return 0;
}
|
参考URLの文字列入れるの忘れたので再投稿。 ついでに、delete_bak の引数として複数のディレクトリパス名を取るようにした。 引数なしの場合は、カレントディレクトリ(./)がデフォルトでセットされる。
see: jmuk さんのコード
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | require 'find'
def delete_bak(dir_path = './')
Find.find("#{dir_path}") do |path|
if File.file?(path) && path =~ /~$/
File.unlink(path)
end
end
end
if ARGV.empty?
delete_bak
else
ARGV.each{|arg| delete_bak(arg)}
end
|
SML# 0.30ではreadDirでparentArcとcurrentArcも拾ってしまうので、 明示的にパターンマッチしています。 Basis Libraryの仕様通りの挙動なら | SOME "." => loop () | SOME ".." => loop () このコードは不要です。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | fun remove_backup path =
let
open OS.FileSys
val dir = openDir path
fun loop () =
case readDir dir of
NONE => ()
| SOME "." => loop ()
| SOME ".." => loop ()
| SOME file => if isDir file then (remove_backup file;loop ())
else if String.isSuffix "~" file then (remove file;loop ())
else loop ()
in
chDir path;
loop ();
closeDir dir;
chDir (OS.Path.parentArc)
end
|
プログラム(修正版)にまだバグがあった.POSIX系のファイルシステムでは, シンボリックリンクでディレクトリパスに循環があると停止しなくなってしまう.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | module Main (main) where
import System.Directory ( setCurrentDirectory, getCurrentDirectory
, getDirectoryContents
, removeDirectoryRecursive, removeFile )
import System.Posix.Files (getSymbolicLinkStatus, isDirectory)
import System.Environment (getArgs)
main :: IO ()
main = getArgs >>= mapM_ cleaning
cleaning :: FilePath -> IO ()
cleaning = (>> removeBackupFiles) . setCurrentDirectory
removeBackupFiles :: IO ()
removeBackupFiles
= do { cwd <- getCurrentDirectory
; getDirectoryContents "." >>= mapM_ (rmbk cwd) . drop 2
}
rmbk :: FilePath -> FilePath -> IO ()
rmbk cwd path
= do { fstat <- getSymbolicLinkStatus path
; let backup = '~'== last path
; if isDirectory fstat
then if backup then removeDirectoryRecursive path
else cleaning path >> setCurrentDirectory cwd
else if backup then removeFile path
else return ()
}
|
dmd 2.007で。
listdir(".","*~")を使ったら固まった。
てことで、if使うことに。
see: std.file
1 2 3 4 5 | import std.file;
import std.regexp;
void main(string[] argv) {
foreach (string d; listdir(argv[1])) if(d[$-1]=='~') remove(d);
}
|
ワンライナーで。
1 | path="";pathの全ファイル列挙を反復;もし((正規表現マッチ(対象,"~$"))<>"")なら,対象をファイル削除
|
boost::filesystemはあまり使ったことないので勉強がてら.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | #include <iostream>
#include <boost/filesystem/fstream.hpp>
void removeBackupFile(const boost::filesystem::path& dir)
{
namespace fs = boost::filesystem;
if (fs::exists(dir)) {
for (fs::directory_iterator i(dir), end; i != end; ++i) {
if (fs::is_directory(i->status())) {
removeBackupFile(i->path());
} else {
const std::string& name = i->path().leaf();
if (name[name.size() - 1] == '~') {
// std::cout << "remove:" << i->path() << std::endl;
fs::remove(i->path());
}
}
}
}
}
int main(int argc, char *argv[])
{
if (argc == 1) {
std::cerr << argv[0] << " dir" << std::endl;
return 1;
}
try {
removeBackupFile(argv[1]);
} catch (boost::filesystem::filesystem_error& e) {
std::cerr << "err:" << e.what() << std::endl;
}
return 0;
}
|
いきなり消すと怖いので、確認機能付き。
FileUtils.rmでまとめて消します。
(いちど言語を指定せずに投稿してしまったので再投稿します。以後気をつけますorz)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | require "fileutils"
dir = "/どこかのディレクトリ/"
pattern = /~$/
rm_path_list = []
#パターンにマッチするファイルを探す
Dir.glob("#{dir}**/*").each do |path|
if File.basename(path) =~ pattern
rm_path_list << path
puts "- " + path
end
end
if rm_path_list != []
answer = ""
#削除するか質問する(yかnが入力されるまで繰り返す)
until /[yn]/ =~ answer
print "削除しますか[yn]? "
answer = gets.chomp
case answer
when "y"
begin
#該当ファイルの配列からまとめて削除
FileUtils.rm(rm_path_list)
rescue
puts "削除に失敗しました。"
end
when "n"
puts "中止しました。"
end
end
else
puts "パターンにマッチするファイルがありません。"
end
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | import System
import System.Directory
import System.Posix.Directory
import System.IO.Unsafe
import System.Posix.Files
import System.FilePath
import System.Environment
readAllEntries :: DirStream -> IO [FilePath]
readAllEntries st =
do s <- readDirStream st
case s of
[] -> return []
_ -> do rest <- unsafeInterleaveIO $ readAllEntries st
return (s:rest)
readChildren :: FilePath -> IO [FilePath]
readChildren p =
do st <- getFileStatus p
if isDirectory st
then unsafeInterleaveIO $ (walkDir p)
else return []
walkDir :: FilePath -> IO [FilePath]
walkDir path =
do ents <- openDirStream path >>= readAllEntries
child <- mapM readChildren $ map join $ filter ((/=) '.'.head) ents
return $ map join ents ++ concat child
where join = joinPath.(++) [path].flip (:) []
rmbk :: FilePath -> IO()
rmbk a = walkDir a >>= mapM_ removeFile.filter ((==) '~'.last)
main :: IO()
main = getArgs >>= mapM_ rmbk
|
1 2 3 4 5 6 7 8 9 10 11 | require 'ftools'
def clean_nyoro(file)
if File.directory?(file)
Dir.glob(file+"/*") do |f|
clean_nyoro(f)
end
elsif /~$/ =~ file
File.rm_f(file)
end
end
clean_nyoro(ARGV.shift || exit)
|
動作環境 Fedora7 Perl5.8.8
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 | #!/usr/bin/perl
use strict;
exit main();
sub main {
if(@ARGV != 1){
print "usage: perl 3361.pl <target-directory>\n";
return -1;
}
my $dir = $ARGV[0];
my $loop = 0;
$dir =~ s/ (.*)\/$/$1/;
if(! -d $dir){
print "Can't open $dir\n";
return -2;
}
return del_file($dir,$loop);
}
sub del_file {
no strict 'refs';
my ($dir,$loop) = @_;
if(!opendir(DIR.$loop,$dir)){
print "$dir $!\n";
return ($loop > 0) ? $loop - 1 : $loop;
}
while(my $file = readdir(DIR.$loop)){
next if($file =~ / \.{1,2}$/);
my $dir_file = "$dir/$file";
if(-d $dir_file){
$loop = del_file($dir_file,++$loop);
}
elsif($file =~ /~$/){
if(!unlink($dir_file)){
print "$dir_file $!\n";
}
else{
print "$dir_file delete\n";
}
}
}
closedir DIR.$loop;
return ($loop > 0) ? $loop - 1 : $loop;
}
|
特にひねりなしです。
1 2 3 4 5 6 7 | def dir = new File("c:/work")
dir.eachFileRecurse{
if( it.file && it.name.endsWith("~") ){
file.delete()
}
}
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | #load "unix.cma";;
let dir_fold f acc path =
let dir = Unix.opendir path in
let acc = ref acc in
try
while true do
match Unix.readdir dir with
| "." | ".." -> ()
| s -> acc := f !acc (Filename.concat path s)
done; assert false
with err -> Unix.closedir dir;
if err=End_of_file then !acc else (raise err);;
let dir_iter_rec =
let file_iter f path =
dir_fold (fun acc s ->
match (Unix.stat s).Unix.st_kind with
| Unix.S_DIR -> (s::acc)
| _ -> f s; acc
) [] path in
let rec iter_rec f ls =
List.iter (fun path -> iter_rec f (file_iter f path)) ls
in
(fun f path -> iter_rec f (file_iter f path));;
let rmbak path =
dir_iter_rec (fun s ->
if Filename.check_suffix s "~" then Unix.unlink s
) path;;
|
VBA for Excel (2003)。デストローイ。ノーフューチャー。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | Sub Main()
Dim p, o
With Application.FileDialog(msoFileDialogFolderPicker)
.Show
p = .SelectedItems(1)
Set o = CreateObject("Scripting.FileSystemObject")
Call Df(p, o)
End With
End Sub
Sub Df(p, o)
Dim f, d
With o.GetFolder(p)
For Each f In .Files
If Right(f.Name, 1) = "~" Then
f.Delete
End If
Next
For Each d In .SubFolders
Call Df(p + "\" + d.Name, o)
Next
End With
End Sub
|
os.walkは便利ですが、再帰を書きたかったのであえて使わずに書いてみました。
あとは本当は例外処理部分を追加したほうが良さそうですね(コマンドライン引数が正しくない場合や、引数に不正なパスを指定した場合の処理等)。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | import os
import sys
def delete_tilde(path):
for f in (os.path.join(path, x) for x in os.listdir(path)):
if os.path.isdir(f):
delete_tilde(f)
elif f[-1] == "~":
os.remove(f)
print f, "is deleted."
if len(sys.argv) != 2:
print "usage: %s pathname" % (sys.argv[0])
else:
target_dir = os.path.abspath(sys.argv[1])
delete_tilde(target_dir)
|
AntBuilderを使ってみました。 なお、「**/*~」はデフォルト除外パターンらしいので、 「defaultexcludes:'no'」とすることで、これを回避しています。
see: deleteタスク - Deleteタスク(削除) - Apache Antの使い方
1 2 | def ant = new AntBuilder()
ant.delete(dir:'c:/work', includes:'**/*~' defaultexcludes:'no')
|
daleteFilesBySuffixメソッド内で"~"ベタ書きしてたら引数の意味なくね?
1 2 3 4 5 6 7 8 | public void daleteFilesBySuffix(final String suffix) {
FileFilter filter = new FileFilter() {
public boolean accept (File pathname) {
return pathname.isFile() && pathname.getName().endsWith(suffix);
}
};
deleteTargetFiles(rootDir, filter);
}
|
File::Find::Rule で削除対象ファイルをリストとして取得。あとでまとめて削除している。 コードが長いのは消す確認を2度しているのと、Optionをお約束で入れてみたから。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 | #! /opt/local/bin/perl
use strict;
use warnings;
use Getopt::Long;
use File::Find::Rule;
# Remove all files matching $TARGET_REGEX
my $TARGET_REGEX = qr/~$/;
my %options = (
"debug" => undef, # debug mode
);
GetOptions (
"debug" => \$options{debug},
) || die("failed GetOptions");
sub main()
{
my @dir = ("."); # default
@dir = @ARGV if @ARGV;
firstConfirm(\@dir);
rmR(\@dir);
}
sub firstConfirm(\@)
{
my $dir = shift;
for my $d (@$dir) {
print $d, "\n";
die("Usage: $0 dir1 dir2 ") if ! -d $d;
}
print STDERR qq/[WARNING] removing files ending with "~" under "@$dir" directory.\n/;
my $confirm_str = "I want to continue";
print STDERR qq/Execute? [Type "$confirm_str"]: /;
chomp(my $line = <STDIN>);
if ($line !~ $confirm_str) {
print STDERR "bye\n";
exit(0);
}
}
sub rmR(\@)
{
my $dir = shift;
print STDERR "[DEBUG] removing under @$dir\n" if defined $options{debug};
my @files_to_remove = File::Find::Rule->file()
->name($TARGET_REGEX)
->in(@$dir);
my $f_count = @files_to_remove;
if ( defined $f_count && ($f_count == 0) ) {
print STDERR "\nNo file[s] to remove found.\n";
exit(0);
}
doRm(\@files_to_remove) if finalConfirm(\@files_to_remove);
}
sub finalConfirm(\@)
{
my $files_to_remove_ref = shift;
my $result ;
print "unlinking:\n";
print map "\t\t$_\n", @$files_to_remove_ref;
print "continue?[y/n]: ";
my $ans = <STDIN>;
$result = 1 if $ans =~ m/y(es){0,1}/i;
return $result;
}
sub doRm(\@)
{
my $dir_ref = shift;
unlink @{$dir_ref};
}
main();
|
Lost_dogです。Haskellでディレクトリ操作をしようとしたら、いろんな困難にぶち当たりました。IOモナドははびこるし、環境変数とかいう見えないグローバル変数に悩まされるし…
これは現行のOSインターフェースとHaskellがいかに相性が悪いかということを物語ってます。
GHCiをシェル代わりに使いたいんですが、現行のディレクトリ関係のモジュールは、完全にOSインターフェースをなぞっているだけで、まったくHaskellらしさがなく、使い勝手が極めて悪いです。まあ、自分で作れってことですね。。
で今回のお題ですが、ディレクトリを再帰的に扱うっていう、よくある作業です。最初は
recursive f dir
みたいなインターフェースを考えました。でもディレクトリっていうのはツリー構造なんだから、ツリーとして扱うべきなんじゃないかと思い、
lsTree dir >>= mapM f
みたいな形にしました。いかがでしょうか。
ちなみに、2010年の私の夢は、bashがすべてhaskellに置き換わることですw
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | module Main where
import Prelude hiding (mapM)
import Data.Tree
import Data.List
import Data.Traversable
import System.Directory
import System.FilePath
import System.Environment
main = getArgs
>>= lsTree.head
>>= mapM (doOnFileIf (isSuffixOf "~".takeFileName) removeFile)
isDir = doesDirectoryExist
isFile = doesFileExist
ls :: FilePath -> IO [FilePath]
ls d = fmap (map (d</>).(\\[".",".."])) $ getDirectoryContents "."
lsTree :: FilePath -> IO (Tree FilePath)
lsTree = unfoldTreeM f
where f x = do p <- isDir x
if p then do fs <- ls x; return (x, fs)
else return (x, [])
doOnFileIf :: (FilePath -> Bool) -> (FilePath -> IO ()) -> FilePath -> IO ()
doOnFileIf p f x = do q <- isFile x
if p x && q then f x else return ()
|
すみません、コードみすってました。。lsが間違ってます。正しくは以下です。
1 2 | ls :: FilePath -> IO [FilePath]
ls d = fmap (map (d</>).(\\[".",".."])) $ getDirectoryContents d
|






にしお
#3361()
Rating1/1=1.00
[ reply ]