【问题标题】:How do I delete files from all subdirectories but not from hidden directories?如何从所有子目录中删除文件,而不是从隐藏目录中删除文件?
【发布时间】:2012-03-05 20:56:09
【问题描述】:
我只想删除所有子目录中的文件,而不是删除以. 开头的隐藏目录中的任何文件。示例:
Directory
├── file1
├── file2
├── .hidden directory
│ ├── log
│ └── txt
└── subdir
├── file a
└── file b
如何删除file1、file2、file a和file b?那不应该删除log 和txt。
【问题讨论】:
标签:
perl
bash
shell
scripting
【解决方案1】:
这是一个带有find的1-liner
find . -path "*/.*" -prune -o \( -type f -exec rm {} + \)
示例
$ find .
.
./.hidden
./.hidden/log
./.hidden/txt
./file1
./file2
./subdir
./subdir/filea
./subdir/fileb
$ find . -path "*/.*" -prune -o \( -type f -exec rm {} + \)
$ find .
.
./.hidden
./.hidden/log
./.hidden/txt
./subdir
【解决方案2】:
这里有一个小潜艇在做这项工作:
sub clean_dir
{
my $dir = shift;
require File::Spec;
if ($dir && -d $dir && opendir(DIR, $dir))
{
my @all = grep { -d (File::Spec->join($dir, $_) && m/^\./) } readdir(DIR);
@all = map { File::Spec->join($dir, $_) } @all;
closedir(DIR);
foreach my $f (grep { -f $_ } @all) {
unlink($f);
}
foreach my $d (grep { -d $_ } @all) {
clean_dir($d);
}
}
}
File::Spec 用于正确处理元素分隔符,即“/”、“\”或您系统上使用的任何其他字符。
【解决方案3】:
一种方式:
运行脚本之前的文件树:
ls -1aR Directory/
输出:
Directory/:
.
..
file1
file2
.hidden
subdir
Directory/.hidden:
.
..
log
txt
Directory/subdir:
.
..
filea
fileb
script.pl的内容:
use warnings;
use strict;
use File::Find;
die qq[Usage: perl $0 <directory>\n] unless @ARGV == 1;
die qq[Argument must be a directory\n] unless -d $ARGV[0];
find( \&wanted, $ARGV[0] );
sub wanted {
if ( -d && m/\A\.[^.]/ ) {
$File::Find::prune = 1;
return;
}
if ( -f ) {
unlink $_ or warn qq[Cannot delete $File::Find::name\n];
}
}
运行脚本:
perl script.pl Directory
运行脚本后的文件树:
Directory/:
.
..
.hidden
subdir
Directory/.hidden:
.
..
log
txt
Directory/subdir:
.
..