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!



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.


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 {} \;

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).


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.


... 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
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.