Ci sono essenzialmente 2 metodi che puoi usare per farlo. Uno analizzerà la stringa mentre l'altro opererà su ciascun file. L'analisi della stringa utilizza uno strumento come grep
, sed
o awk
sarà ovviamente più veloce, ma ecco un esempio che mostra entrambi, oltre a come "profilare" i 2 metodi.
Dati di esempio
Per gli esempi seguenti utilizzeremo i seguenti dati
$ touch dir{1..3}/dir{100..112}/file{1..5}
$ touch dir{1..3}/dir{100..112}/nile{1..5}
$ touch dir{1..3}/dir{100..112}/knife{1..5}
Elimina alcuni *f*
file da dir1/*
:
$ rm dir1/dir10{0..2}/*f*
Approccio n. 1 - Analisi tramite stringhe
Qui stiamo andando a utilizzare i seguenti strumenti, find
, grep
, e sort
.
$ find . -type f -name '*f*' | grep -o "\(.*\)/" | sort -u | head -5
./dir1/dir103/
./dir1/dir104/
./dir1/dir105/
./dir1/dir106/
./dir1/dir107/
Approccio n. 2: analisi tramite file
Stessa catena di strumenti di prima, tranne che questa volta useremo dirname
invece di grep
.
$ find . -type f -name '*f*' -exec dirname {} \; | sort -u | head -5
./dir1/dir103
./dir1/dir104
./dir1/dir105
./dir1/dir106
./dir1/dir107
NOTA: gli esempi sopra riportati stanno head -5
semplicemente limitando la quantità di output con cui abbiamo a che fare con questi esempi. Normalmente verrebbero rimossi per ottenere il tuo elenco completo!
Confronto dei risultati
Possiamo usare time
per dare un'occhiata ai 2 approcci.
dirname
real 0m0.372s
user 0m0.028s
sys 0m0.106s
grep
real 0m0.012s
user 0m0.009s
sys 0m0.007s
Quindi, se possibile, è sempre meglio occuparsi delle stringhe.
Metodi alternativi di analisi delle stringhe
grep & PCRE
$ find . -type f -name '*f*' | grep -oP '^.*(?=/)' | sort -u
sed
$ find . -type f -name '*f*' | sed 's#/[^/]*$##' | sort -u
awk
$ find . -type f -name '*f*' | awk -F'/[^/]*$' '{print $1}' | sort -u
uniq
nel mix aiuta molto rimuovendo le linee ripetute che sono già una accanto all'altra.find . -type f -name '*f*' -printf '%h\0' | uniq -z | sort -zu | tr '\0' '\n'
. Oppure, se i tuoi strumenti sono un po 'più vecchi, uniq potrebbe non avere l'opzione -z.find . -type f -name '*f*' -printf '%h\n' | uniq | sort -u