Script Bash para listar itens no diretório por tamanho

1

Como escrevo um script para cada argumento, o script deve exibir o maior item no diretório junto com seu tamanho. Algo parecido com isto:

[user]$ maxls /boot 2> /dev/null | sort -n
1024 /boot/grub2/themes/stars
8101 /boot/grub2/pic.png
    
por bbycakes3 26.10.2015 / 04:07

4 respostas

0

#!/bin/sh
for dir
do
    [ -d "$dir" ] || continue
    du -hs "$dir"/* | sort -hr | sed  1q
done
    
por 26.10.2015 / 04:45
0

Usando perl eu usaria algo assim:

#!/usr/bin/env perl
use strict;
use warnings;

use File::Find;

my %biggest_file_in;
my %biggest_file_size_in;

sub max_in_path {
    my ($dir) = @_;
    return unless -f;
    if ( -s > ( $biggest_file_size_in{$dir} // 0 ) ) {

        $biggest_file_in{$dir}      = $File::Find::name;
        $biggest_file_size_in{$dir} = -s;
    }
}


my ($path_to_search) = @ARGV;
die "Specify a path" unless $path_to_search;
foreach my $dir ( glob("$path_to_search/*") ) {
    next unless -d $dir;
    find( sub { max_in_path($dir) }, $dir );
    print $dir, ":", $biggest_file_in{$dir}, " =>",
        $biggest_file_size_in{$dir}, "\n";
}


print "Largest files in individual directories (sorted):\n";
foreach my $dir ( sort 
                     { $biggest_file_size_in{$b} <=> $biggest_file_size_in{$a} } 
                         keys  %biggest_file_size_in ) { 
    print "$dir $biggest_file_in{$dir} $biggest_file_size_in{$dir}\n";
}

Nota - funciona para todos os diretórios no diretório especificado. (por exemplo: myfind.pl /data pesquisará /data/* - mas ignore todos os arquivos presentes em /data );

    
por 26.10.2015 / 16:57
0

O shell zsh tem suporte embutido para isso:

#! /bin/zsh -
zmodload zsh/stat &&
for dir {
  largest=(${dir:-.}/**/*(NDOL[1]))
  (($#largest)) || largest=${dir:-.}
  zstat -A size +size -- "$largest" &&
    print -r -- $size $largest
}
    
por 26.10.2015 / 17:55
-1
# m_all [dir=.]...: lists the biggest file in *all* the directories.
#   du options can be specified using $DU_OPTS; the recommend value is '-h'.
m_all(){ find "$@" -type f -print0 | du $DU_OPTS --files0-from=-; }
# maxls: for each argument, list the biggest $maxls_n items.
#   If $maxls_n is undefined or empty, use 1.
#   Additional arguments to pass to m_all can be defined in the array mallargs; see examples below.
maxls(){ local i; for i; do m_all "$i" "${mallargs[@]}" | sort -h | tail -n "${maxls_n:-1}"; done; }
#_Example:
# list the biggest file for /bin and /usr respectively
maxls /bin /usr
# list the biggest 5 files for /home and /root
maxls_n=5 maxls /home /root
# Let maxls count only *.avi, *.svg and *.mp4:
mallargs=(-iregex '.*\.\(avi\|svg\|mp4\).*')
# And run it against ~/Anime
maxls ~/Anime; mallagrs=() # clear that setting
# And use m_all to list the biggest five logs:
DU_OPTS=-h m_all /var -name '*.log*' | sort -h | tail -n 5

E você pode até adicionar find filtros!

Editar : adicionado para cada um. Obrigado a RobertL por apontar isso. E documentação.

Se você quiser isso como um script, crie um novo arquivo que diga #!/bin/bash , copie as linhas com (){ e adicione maxls "$@" . Pessoalmente eu não gosto de encher meus ~/bin com scripts super-triviais.

Explicação / changelog

A partir do exemplo, podemos ver arquivos em subdiretórios, e a coisa é invocada com um sort -h extra. Como o diretório inteiro definitivamente não é menor do que os arquivos contidos nele, concluo que os itens estão limitados apenas a arquivos.

A partir desse ponto, obtive a solução inicial, agora chamada de m_all . Não podemos saber quais são os maiores, a menos que os classifiquemos, por isso, foi adicionado um valor extra de tail pass no exemplo inicial.

Com algum patch, esta é a versão 3, mas isso é um buggy, já que o usuário quer para cada argumento . Eu mudei o nome para m_all , deixando um wrapper chamado maxls , pois presumo que o antigo ainda tenha algum uso e eu quero minimizar minhas alterações (v4). Como sempre faço, deixei um punhado de interruptores para mudar seu comportamento. Depois disso, como você pode ver, a documentação foi adicionada (v5-7).

Por favor, esteja ciente de que com o comportamento foreach , geralmente não faz sentido usar qualquer tail ou sort depois que tudo estiver pronto. Você tem que usar sort toda vez que você obtiver essa saída. tail imprime as últimas linhas de cada arquivo, mas vai tornar o código super longo.

    
por 26.10.2015 / 04:13