2015-11-28 14 views
5

Desidero elencare le directory contenenti le dimensioni dei file comprese in un intervallo. La mia soluzione è di guardare ogni directory e se tutte le sue dimensioni di file sono nell'intervallo, mostrarlo in uscita. Voglio sapere se esiste un modo più semplice per controllare come un interruttore nel comando find o qualsiasi altro comando come questo.Elenca le directory in cui le dimensioni dei file rientrano nell'intervallo

per esempio: l'intervallo = 10 - 20

dir1: 
f1 size=12 
f2 size= 19 

dir2: 
f3 size=22 
f4 size=11 

OUTPUT = dir1 

dir2 è escluso perché f3 non rientra nell'intervallo 10-20. dir1 non è escluso, perché tutti i suoi file hanno dimensioni all'interno dell'intervallo.

+2

Prova '' du' e awk'. – Cyrus

+3

Senza commentare se sia meglio "usare' du' e 'awk'", si può certamente farlo con uno pseudo-one-liner che coinvolge 'find':' per dir in dir1 dir2; do [[-z "$ (trova" $ dir "-type f \ (-size -10c -o -size + 20c \) 2>/dev/null)"]] && echo "$ dir"; done'. (Dovresti ottenere 'dir1' come output.) – 4ae1e1

+1

intendi la dimensione totale dei file in una directory o la dimensione di un file? – OznOg

risposta

2

Codice di prestito del commento di 4ae1e1:

Trova la prima eccezione alla regola (se presente) in ciascuna sottodirectory specificata dalla riga di comando. Stampa questo se è permesso.

dir_filesize_rangefilter() { 
    # args: lo hi paths... 
    # sizes in MiB 
    # return value: dir names printed to stdout 
    local lo=$1 hi=$2 
    shift 2 # "[email protected]" is now just the paths 

    for dir; do # in "[email protected]" is implicit 
     local safedir=$dir 
     [[ $dir = /* ]] || safedir=./$dir # make sure find doesn't treat weird -filenames as -options 
     # find the first file smaller than lo or larger than hi 
     [[ -z "$(find "$safedir" -type f 
       \(-size "-${lo}M" -o -size "+${hi}M" \) 
       -print -quit)" 
     ]] && printf '%s\n' "$dir" 
    done 
} 

ho usato "printf", perché si rompe "echo" se uno dei nomi delle directory inizia con -e o qualcosa del genere. Si potrebbe avere questo aggiungere le directory consentite a un array, invece di stamparle sullo stdout, se si vuole essere paranoici sui nomi di file validi (poiché si dovrebbe analizzare l'output di questo con un ciclo while IFS= read o qualcosa per consentire qualsiasi carattere , e che rompe ancora sui nomi dir che contengono una nuova riga)

a quanto pare è così l'evidenziazione della sintassi non conosce le regole di quoting per le citazioni all'interno $(command substitution):./

+1

Parlando di nomi di directory stupidi che iniziano con un trattino, interromperanno anche 'find' ... Quindi usare' ./$ dir' se non è assoluto è probabilmente meglio. – 4ae1e1

+0

@ 4ae1e1: buona presa; fisso. Non riuscivo a pensare a un'espansione intelligente $ {dir/pattern/replace} 'per farlo senza l'assegnazione condizionale della variabile temp a due fasi. –

+0

'$ {dir /#-/./-}'? Comunque, un po 'troppo hackerato per i miei gusti. Sono tutto per codice prolisso ma autodocumentante. – 4ae1e1

1

Ecco una possibile soluzione in 3 linee. Ho dato un esempio concreto:

  1. Elenco di tutti i file più grande di 1 MB in un file: du -hat 1M > gr.dat

  2. Elenco di tutti i file più piccolo di 3MB in un file diverso: du -hat -3M > sm.dat

  3. Usa grep per trovare le corrispondenze in entrambi i file generati: grep -F -x -f gr.dat sm.dat

+0

Trova le directory contenenti almeno un file consentito, non le directory che contengono * solo * i file consentiti. Come 4ae1e1 suggerito nei commenti, è possibile generare un elenco di file non consentiti e quindi stampare solo le directory che non contengono nessuno di questi. –

+0

Vero, grazie per averlo sottolineato! – proteus

Problemi correlati