查找目录树

时间:2017-10-20 15:56:40

标签: linux perl sed find

我需要找出树中哪些目录中的文件最多(但不在其子目录中)。不应计算目录。

这很容易与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";

3 个答案:

答案 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