Modificação requerida para o comando perl

0

Eu preciso de uma modificação para o comando perl abaixo:

perl -wE 'say for ((sort { -s $b <=> -s $a } </tmp/?>)[0..9]);'

Requisito:

  1. Ele deve verificar todos os subdiretórios dentro do diretório de destino.
  2. Anote os 10 principais arquivos com seu tamanho e caminho.
por Anoop Kumar KR 18.05.2018 / 12:37

4 respostas

2

Este script perl irá imprimir exatamente o que você precisa, ele está usando File::Find para percorrer recursivamente. Eu usei -f para garantir que apenas os arquivos sejam colocados no hash

O hash %files tem filepath como chave e size como seu valor. Em seguida, classificou-o com base em valores e imprimiu os 10 melhores resultados

#!/usr/bin/perl

use strict;
use warnings;
use File::Find;

my %files;
my $counter=0;
find( \&wanted, '<target directory>');
for my $file  ( sort {$files{$b} <=> $files{$a}}  keys%files){
        print "$file : $files{$file}\n";
        $counter++;
        if ($counter == 10){
                last;
        }
}


sub wanted {
  $files{"$File::Find::name"}=-s $File::Find::name if -f;
  return;

}

Ou simplesmente usando uma matriz para fazê-lo funcionar

#!/usr/bin/perl

use strict;
use warnings;
use File::Find;

my @files;
my $counter=0;
find( \&wanted, '<target directory>');
for my $file  ( sort { -s $b <=> -s $a}  @files){
        my $size = -s $file;
        print "$file : $size\n"
        $counter++;
        if ($counter == 10){
                last;
}
sub wanted{
  push @files,$File::Find::name if -f;
  return;
}
    
por 18.05.2018 / 13:01
2

Use File :: Find para percorrer recursivamente a árvore de diretórios:

perl -MFile::Find -wE '
    find(sub { push @all, $File::Find::name }, "/tmp");
    say for (sort { -s $b <=> -s $a } @all)[0..9]'

Se houver muitos arquivos, você receberá Out of memory , retornará os tamanhos e usará sort e head externos para limitar a saída:

perl -MFile::Find -wE 'find(sub { say -s $_, " $File::Find::name" }, "/tmp")' \
| sort -nr | head -n10
    
por 18.05.2018 / 12:50
1
zsh -c 'ls -ldS /tmp/**/?(DOL[1,10])'

Para l i s t, os arquivos 10 L de caracteres únicos ( ? ) em /tmp e subdirs ( **/ ), ordenados por S ize.

Com perl e para evitar o armazenamento de toda a lista de arquivos na memória quando você deseja apenas os 10 maiores:

perl -MFile::Find -e '
  find(
    sub {
      if (length == 1 && $_ ne ".") {
        @s = sort {$b->[0] <=> $a->[0]} [-s, $File::Find::name], @s;
        splice @s, 10
      }
    }, "/tmp"
  ); printf "%16d %s\n", @{$_} for @s'

(o length == 1 && $_ ne "." deve corresponder aos nomes de arquivos de byte único, como seu /tmp/? sugere que você queira fazer).

Em vez de printf "%16d %s\n", @{$_} , você também pode executar ls , como na zsh solution com exec "ls", "-ldS", map $_->[1], @s

    
por 18.05.2018 / 14:27
0

mais fácil com o bash eu diria

find ${PATH_TO_PARENT_FOLDER} -type f -exec du -ahx {} + | sort -rh | head -10

Essencialmente, estamos usando find para localizar todos os arquivos dentro de uma pasta,

  • -type f para arquivo ou d para dir
  • -exec executa um comando usando a saída de find e coloca o resultado como argumento em {}

em seguida, executando du para calcular o tamanho de cada elemento encontrado por meio da localização e adição

  • -a, --all escreve contagens para todos os arquivos, não apenas diretórios
  • -h, --human-readable tamanhos de impressão em formato legível por humanos (por exemplo, 1K 234M 2G)
  • -x, --one-file-system ignora diretórios em diferentes sistemas de arquivos

Em seguida, canalizamos para classificá-la de maior para menor e usamos a cabeça para apresentar apenas os 10 primeiros

sort para classificar o resultado da saída

  • -h, --human-numeric-sort compara números legíveis por humanos (por exemplo, 2K 1G)
  • -r, --reverse inverte o resultado das comparações

head apenas para ler os resultados principais

  • -<N> para definir a quantidade de linhas que você deseja ver de 1 a N
por 18.05.2018 / 12:58

Tags