Trovare ricorsivamente il file più grande


41

Sto cercando di trovare ricorsivamente il file più grande in una directory. Se c'è una sottodirectory all'interno di quella directory, la funzione deve andare all'interno di quella directory e verificare se c'è il file più grande. Una volta trovato il file più grande, l'output viene visualizzato con il nome del percorso relativo, il nome e la dimensione del file più grande.

EX:

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

Questo è quello che ho:

#!/bin/sh
clear

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

Sono bloccato da un po 'di tempo. Non riesco ad implementare questo tramite il pipelining di una serie di strumenti Unix esistenti. Qualsiasi idea sarebbe bella!



andare in soli subdirs: for d in */ .[^.]*/; fare ... `
Olivier Dulac il

Risposte:


54

usare find(qui assumendo GNU find) per produrre nomi di file con le dimensioni del file. ordinare. stampare il più grande.

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

Ciò presuppone che i percorsi dei file non contengano caratteri di nuova riga.


Uso di un loop in bashcon l'implementazione GNU di 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"

Questo sarà significativamente più lento della soluzione di ricerca. Ciò presuppone anche che i nomi dei file non finiscano in caratteri di nuova riga e salteranno i file nascosti e non scenderanno nelle directory nascoste.

Se esiste un file chiamato -nella directory corrente, verrà considerata la dimensione del file aperto su stdin.

Fare attenzione che le versioni bashprecedenti alla 4.3 seguissero i collegamenti simbolici durante la discesa dell'albero delle directory.


Grazie, funziona! Apprezzo l'aiuto. Sto cercando di abituarmi alla programmazione in shell. In questo momento non ne so molto, quindi apprezzo che tu mi dica cosa sta succedendo con quella riga di codice.
user2419571

Domanda veloce: per curiosità c'è un modo per farlo senza comandi di piping? Sono curioso perché ogni esempio che ho visto ha usato tubature di qualche tipo.
user2419571

2
Sono sicuro che ci sono altri modi per farlo. La filosofia UNIX è che gli strumenti dovrebbero essere monouso e metterli insieme in modo che l'output di un comando sia inserito nell'input del successivo.
Glenn Jackman,

Ciò ha senso. Grazie ancora per il tuo aiuto.
user2419571

2
@ user2419571:; tail -n 1 <(sort -n <(find . -type f -printf "%s\t%p\n")))
Ciro

9

Questo comando aiuta anche a elencare le dimensioni definite.

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

5

Funziona su BSD / macOS:

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

È inoltre possibile aggiungere | head -n 3per visualizzare il numero di voci interessanti (3 in questo caso).


1
Questa risposta potrebbe essere migliorata spiegando come funziona. Inoltre, sembra molto simile alla risposta accettata (che non spiega completamente come funziona neanche).
dhag,

man finde man sortusa brainz :-)
CeDeROM il

Non funziona davvero su MacOS in quanto non riesce a restituire correttamente le dimensioni e restituisce un numero enorme di colonne.
sorin,

3

Con zsh, per il file normale più grande:

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

(ovviamente puoi sostituirlo ls -ld --con qualsiasi comando. Se usi GNU lso compatibile vedi anche l' -hopzione per dimensioni leggibili dall'uomo )

  • .: solo file regolari (non directory, collegamenti simbolici, dispositivi, quindici ...)
  • D: includi quelli nascosti e scendi nelle directory nascoste
  • OL: ordine inverso per dimensione ( Length).
  • [1]: solo la prima partita.

Se ci sono legami, ne otterrai uno a caso. Se vuoi il primo in ordine alfabetico, aggiungi un extra on( order per name) per ordinare i legami in ordine alfabetico.

Si noti che considera la dimensione dei file, non l'utilizzo del disco.


... Comincio a credere che tu sia sul libro paga di zsh;) (quale potrebbe benissimo essere?). sfortunatamente zsh non è disponibile su tutti i sistemi ...
Olivier Dulac il

È possibile ottenere i primi dieci file? (Senza fare qualcosa di stupido come un ciclo)
Wowfunhappy,

1
@Wowfunhappy sostituisce [1]con[1,10]
Stéphane Chazelas il
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.