我需要找出树中哪些目录中的文件最多(但不在其子目录中)。不应计算目录。
这很容易与bash,Perl,Python,Tcl等一起使用,但将它解决为单行很有意思。
我写了以下正确计算的单行
ls -Rp1 | grep -vP '\/$' | perl -pe 's/\n/ /' | perl -e '$ln=<>;@ds=split/(?=\.\/)/,$ln;for(@ds){($d,$fs)=split/:/;$fs=~s/^\s+|\s+$//;$c=split/\s+/,$fs;$fc+=$c;print "$c $d\n"}print "Totals: dirs: @{[scalar @ds]}, files: $fc\n"' | sort -n
有没有更优雅的单行解决方案来实现这一点,不一定是Perl?
这是等效的多行
#!/usr/bin/perl
$line = <>;
@dirs = split/(?=\.\/)/, $line;
for ( @dirs ) {
($dir, $files) = split /:/;
$files =~ s/^\s+|\s+$//;
$count = split/\s+/, $files;
$total_files_count += $count;
print "$count $dir\n"
}
print "Totals: dirs: @{[scalar @dirs]}, files: $total_files_count\n";
答案 0 :(得分:2)
这不会起作用吗?
find . -type f | sed -e 's/[^\\/]*$//' | sort | uniq -c | sort -rn | head -10
PS:如果意图是最短的代码,您可能希望将挑战发布到代码高尔夫。
答案 1 :(得分:1)
这样的事情会起作用:
#!/usr/bin/perl
use strict;
use warnings;
countFiles($ARGV[0]);
sub countFiles() {
my $dir=shift;
my @list=glob("$dir/*");
my $count=0;
for (@list) {
if (-d) {
countFiles($_);
}
else {
$count++;
}
}
print "directory=$dir, file count=$count\n";
}
或一个班轮
find . -type f | perl -e 'while(<ARGV>){chomp;s/(.*\/).*$/\1/; $hash{$_}++;}for(keys %hash){print "$_ count=$hash{$_}\n";}'
答案 2 :(得分:1)
Perl&#34; one&#34; -liner,使用核心(高效)File::Find
perl -MFile::Find -wE'
find({no_chdir=>1, wanted => sub { ++$dc{$File::Find::dir} if -f }}, ".");
printf "%4d => $_\n", $dc{$_} for sort { $dc{$b} <=> $dc{$a} } keys %dc;
'
打印(正确)计数&#34;普通&#34;每个目录(而不是其子目录)中的文件(-f
)
45 => . 7 => ./dir/sub_dir_1 4 => ./dir 3 => ./another_dir 2 => ./dir/sub_dir_2
或File::Find::Rule具有更好的界面,并具有不同的输出格式
perl -MList::Util=max -MFile::Find::Rule -wE'
@dirs = File::Find::Rule->directory->in(".");
$dc{$_} = File::Find::Rule->file->maxdepth(1)->in($_) for @dirs;
@skeys = sort { $dc{$b} <=> $dc{$a} } keys %dc;
$ml = max map { length } @skeys;
for (@skeys) { printf "%${ml}s => $dc{$_}\n", $_ }
'
最后三行和-MList::Util=max
仅适用于输出格式。打印
. => 47 dir/sub_dir_1 => 7 dir => 4 another_dir => 3 dir/sub_dir_2 => 2 empty_dir => 0