Básicamente, existen 2 métodos que puede usar para hacer esto. Uno analizará la cadena mientras que el otro operará en cada archivo. El análisis de la cadena usa una herramienta como grep
, sed
o awk
obviamente será más rápido, pero aquí hay un ejemplo que muestra ambos, así como también cómo puedes "perfilar" los 2 métodos.
Data de muestra
Para los ejemplos a continuación usaremos los siguientes datos
$ 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}
Eliminar algunos de los *f*
archivos de dir1/*
:
$ rm dir1/dir10{0..2}/*f*
Enfoque n. ° 1: análisis a través de cadenas
Aquí vamos a utilizar las siguientes herramientas, find
, grep
, y sort
.
$ find . -type f -name '*f*' | grep -o "\(.*\)/" | sort -u | head -5
./dir1/dir103/
./dir1/dir104/
./dir1/dir105/
./dir1/dir106/
./dir1/dir107/
Enfoque n. ° 2: análisis mediante archivos
La misma cadena de herramientas que antes, excepto que esta vez usaremos en dirname
lugar de grep
.
$ find . -type f -name '*f*' -exec dirname {} \; | sort -u | head -5
./dir1/dir103
./dir1/dir104
./dir1/dir105
./dir1/dir106
./dir1/dir107
NOTA: Los ejemplos anteriores se utilizan head -5
para limitar simplemente la cantidad de salida que estamos tratando para estos ejemplos. ¡Normalmente se eliminarían para obtener su listado completo!
Comparando los resultados
Podemos usar time
para echar un vistazo a los 2 enfoques.
dirname
real 0m0.372s
user 0m0.028s
sys 0m0.106s
grep
real 0m0.012s
user 0m0.009s
sys 0m0.007s
Por lo tanto, siempre es mejor lidiar con las cadenas si es posible.
Métodos alternativos de análisis de cadenas
grep y 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
en la mezcla ayuda mucho al eliminar las líneas repetidas que ya están una al lado de la otra.find . -type f -name '*f*' -printf '%h\0' | uniq -z | sort -zu | tr '\0' '\n'
. O si sus herramientas son un poco más antiguas, entonces uniq puede no tener la opción -z.find . -type f -name '*f*' -printf '%h\n' | uniq | sort -u