2013-01-23 12 views
5

Ho una lista di directory in base ai risultati dell'esecuzione del comando "trova" in bash. A titolo di esempio, il risultato di find sono i file:Come ordinare i risultati di find (comprese le directory annidate) alfabeticamente in bash

test/a/file 
test/b/file 
test/file 
test/z/file 

voglio ordinare l'output in modo che appaia come:

test/file 
test/a/file 
test/b/file 
test/z/file 

Esiste un modo per ordinare i risultati entro il comando find, o piping i risultati in ordine?

risposta

9

Se avete la versione GNU di find, provate questo:

find test -type f -printf '%h\0%d\0%p\n' | sort -t '\0' -n | awk -F '\0' '{print $3}' 

di utilizzare questi nomi di file in un ciclo, fare

find test -type f -printf '%h\0%d\0%p\n' | sort -t '\0' -n | awk -F '\0' '{print $3}' | while read file; do 
    # use $file 
done 

Le stampe comando find tre cose per ogni file: (1) la sua directory, (2) la sua profondità nell'albero delle directory e (3) il suo nome completo. Includendo la profondità nell'output, è possibile utilizzare sort -n per ordinare sopra test/a/file. Infine usiamo awk per rimuovere le prime due colonne poiché sono state utilizzate solo per l'ordinamento.

L'utilizzo di \0 come separatore tra i tre campi ci consente di gestire nomi di file con spazi e tabulazioni al loro interno (ma non a tendina, purtroppo).

$ find test -type f 
test/b/file 
test/a/file 
test/file 
test/z/file 
$ find test -type f -printf '%h\0%d\0%p\n' | sort -t '\0' -n | awk -F'\0' '{print $3}' 
test/file 
test/a/file 
test/b/file 
test/z/file 

Se non si riesce a modificare il comando find, quindi provare questa sostituzione contorto:

find test -type f | while read file; do 
    printf '%s\0%s\0%s\n' "${file%/*}" "$(tr -dc/<<< "$file")" "$file" 
done | sort -t '\0' | awk -F'\0' '{print $3}' 

Si fa la stessa cosa, con ${file%/*} viene utilizzato per ottenere il nome di directory di un file e il comando tr viene utilizzato per contare il numero di barre, che equivale alla "profondità" di un file.

(Spero ci sia una risposta più semplice là fuori. Quello che stai chiedendo non sembra così difficile, ma sto tranciatura su una soluzione semplice.)

+1

Sto usando questo comando come parte del mio script di bash. Preferibilmente speravo di poter fare qualcosa sulla falsariga di: 'per file in cerca ... | ordina ... ' – Ken

+0

@Ken Vedi la mia modifica. 'trova ... | mentre read file' dovrebbe essere preferito a 'per file in $ (find ...)'. Quest'ultima non è sicura per gli spazi, è più lenta e può essere ignorata se ci sono troppi nomi di file per adattarsi alla riga di comando. –

-1

provare questo. come riferimento, primeggia sul secondo campo secondario. che esiste solo sul file, e ha una r per il significato inverso, è il primo, dopodiché sarà ordinata sul primo carattere del secondo campo. [-t è il campo deliminator, -k è la chiave]

find test -name file |sort -t'/' -k2.2r -k2.1 

fare un info sort per maggiori informazioni. ci sono un sacco di modi diversi per usare insieme -t e -k per ottenere risultati diversi.

+0

Questo è un modo bizzarro e specifico per ordinare i nomi dei file di esempio. Non è una soluzione generale. –

Problemi correlati