Localizando o maior arquivo recursivamente

41

Estou tentando encontrar o maior arquivo em um diretório recursivamente. Se houver um subdiretório dentro desse diretório, a função precisará entrar nesse diretório e verificar se o arquivo maior está lá. Depois que o arquivo maior é encontrado, a saída é exibida com o nome do caminho relativo e o nome e tamanho do arquivo maior.

EX:

dude@shell2 (~...assignment/solutions) % bash maxfile.sh ~/test
class/asn
dude.h.gch: 9481628

Isto é o que eu tenho:

#!/bin/sh
clear

recursiveS() {
    for d in *; do
        if [ -d $d ]; then
            (cd $d; echo $(pwd)/$line; du -a; recursiveS;)
        fi
    done
}
recursiveS

Estou preso há um tempo agora. Não consigo implementar isso pipelining de várias ferramentas Unix existentes. Alguma idéia seria legal!

user2419571
fonte
para ir em apenas subdirs: for d in */ .[^.]*/; fazer ... `
Olivier Dulac

Respostas:

54

use find(aqui assumindo o GNU find) para gerar nomes de arquivos com o tamanho do arquivo. ordenar. imprima o maior.

find . -type f -printf "%s\t%p\n" | sort -n | tail -1

Isso pressupõe que os caminhos do arquivo não contêm caracteres de nova linha.


Usando um loop bashcom a implementação GNU de stat:

shopt -s globstar
max_s=0
for f in **; do
  if [[ -f "$f" && ! -L "$f" ]]; then
    size=$( stat -c %s -- "$f" )
    if (( size > max_s )); then
      max_s=$size
      max_f=$f
    fi
  fi
done
echo "$max_s $max_f"

Isso será significativamente mais lento que a solução de localização. Isso também pressupõe que os nomes dos arquivos não terminam em caracteres de nova linha e ignoram os arquivos ocultos e não descem para os diretórios ocultos.

Se houver um arquivo chamado -no diretório atual, o tamanho do arquivo aberto no stdin será considerado.

Cuidado que as versões bashanteriores à 4.3 seguiam os links simbólicos ao descer a árvore de diretórios.

Glenn Jackman
fonte
Obrigado, funciona! Agradeço a ajuda. Estou tentando me acostumar com a programação em shell. Eu não sei muito agora, então eu aprecio você me dizendo o que está acontecendo com essa linha de código.
user2419571
Pergunta rápida: Por curiosidade, existe uma maneira de fazer isso sem comandos de tubulação? Estou curioso, porque todos os exemplos que eu vi usaram algum tipo de tubulação.
user2419571
2
Tenho certeza de que existem outras maneiras de fazer isso. A filosofia do UNIX é que as ferramentas devem ter um único objetivo e encadear as mesmas para que a saída de um comando seja inserida na entrada do próximo.
Glenn Jackman
Isso faz sentido. Obrigado novamente por sua ajuda.
User2419571
2
@ user2419571:; tail -n 1 <(sort -n <(find . -type f -printf "%s\t%p\n")))
Cyrus
9

Este comando também ajuda a listar o tamanho definido.

find . -type f -size +100M -exec ls -lh {} \;
senthil sivasamy
fonte
5

Isso funciona no BSD / macOS:

find . -type f -ls | sort -k7 -r

Você também pode anexar | head -n 3para exibir várias entradas interessantes (3 neste caso).

CeDeROM
fonte
1
Esta resposta pode ser melhorada, explicando como funciona. Além disso, é muito semelhante à resposta aceita (que também não explica totalmente como funciona).
dhag
man finde man sort, use brainz :-)
CeDeROM 20/17/17
Não está realmente funcionando no MacOS, pois falha em retornar o tamanho corretamente e retorna um grande número de colunas.
sorin
3

Com zsh, para o maior arquivo regular:

ls -ld -- **/*(.DOL[1])

(é claro que você pode substituir ls -ld --por qualquer comando. Se estiver usando o GNU lsou compatível, consulte também a -hopção para tamanhos legíveis por humanos )

  • .: apenas arquivos regulares (não diretórios, links simbólicos, dispositivos, fifos ...)
  • D: inclua os ocultos e desça em dirs ocultos
  • OL: ordem inversa por tamanho ( Length).
  • [1]: apenas a primeira partida.

Se houver laços, você receberá qualquer um deles aleatoriamente. Se você deseja o primeiro em ordem alfabética, adicione um extra on( order por name) para classificar os laços em ordem alfabética.

Observe que ele considera o tamanho dos arquivos, não o uso do disco.

Stéphane Chazelas
fonte
... Começo a acreditar que você está na folha de pagamento do zsh;) (o que poderia muito bem estar?). zsh não é, infelizmente, disponível em todos os sistemas ...
Olivier Dulac
Possível obter os dez primeiros arquivos? (Sem fazer algo estúpido como um loop)
Wowfunhappy
1
@Wowfunhappy substituir [1]por[1,10]
Stéphane Chazelas