La búsqueda de GNU incluye directorios principales

La búsqueda de GNU incluye directorios principales

Estoy intentando que GNU encuentre entradas excluidas HASTA el nombre de archivo especificado.

Tome este árbol de muestra:

./foo
./foo/another.txt
./foo/bar
./foo/bar/world
./foo/bar/world/test.txt
./foo/bar/world/hello.txt

(Habría muchos otros archivos en los worlddirectorios y otros también, es por eso que no estoy simplemente buscando hello.txt).

Quiero que coincida con todo menos con 'test.txt' y sus directorios principales.

La salida debería ser simplemente foo/bar/world/hello.txt.

Este comando produce los resultados correctos, pero es bastante complicado y produciría resultados incorrectos si hubiera varios directorios con los mismos nombres:

find * ! -name test.txt -a ! -name foo -a ! -name bar -a ! -name world

Respuesta1

Dígale findque solo le interesan los archivos, no los directorios.

find ./foo -type f ! -name test.txt

Actualizar:

Supongamos que tenemos este ejemplo un poco más complejo:

$ find ./foo
./foo
./foo/baz
./foo/baz/b.csv
./foo/baz/a.txt
./foo/bar
./foo/bar/c.txt
./foo/bar/world
./foo/bar/world/hello.txt
./foo/bar/world/test.txt

Si su objetivo es eliminar cosas, debe especificar -depthque los archivos se vean antes que sus directorios:

$ find ./foo -depth
./foo/baz/b.csv
./foo/baz/a.txt
./foo/baz
./foo/bar/c.txt
./foo/bar/world/hello.txt
./foo/bar/world/test.txt
./foo/bar/world
./foo/bar
./foo

Si conoce la ruta que desea conservar, podemos diseñar una expresión regular que coincida con partes de ella:

$ find ./foo -depth -regextype posix-extended -regex '^\./foo(/bar(/world(/test.txt)?)?)?'
./foo/bar/world/test.txt
./foo/bar/world
./foo/bar
./foo

Luego podemos simplemente negar la expresión regular para obtener lo que deseas eliminar:

$ find ./foo -depth -regextype posix-extended ! -regex '^\./foo(/bar(/world(/test.txt)?)?)?'
./foo/baz/b.csv
./foo/baz/a.txt
./foo/baz
./foo/bar/c.txt
./foo/bar/world/hello.txt

Respuesta2

Si conoce la profundidad exacta del árbol (es decir, desea obtener los archivos desde la tercera carpeta en adelante), puede usar:

find . -mindepth $depth ! -name test.txt

Con su estructura de directorio, obtengo:

$ find . -mindepth 4 ! -name test.txt
./foo/bar/world/hello.txt

Que es exactamente lo que esperas.


EDITAR: esto debería ser mejor (¡pero más feo!). Encuentra el directorio donde test.txtse encuentra y encuentra todos los archivos que contiene. La ventaja es que es completamente independiente de las rutas principales, las calculará automáticamente.

EXCLUDEFNAME="test.txt"; find $(find . -name "$EXCLUDEFNAME" -exec dirname {} \; -quit) -mindepth 1 ! -name "$EXCLUDEFNAME"

Multilínea es mejor:

EXCLUDEFNAME="test.txt"
targetpath="$(find . -name "$EXCLUDEFNAME" -exec dirname {} \;)"
find "$targetpath" -mindepth 1 ! -name "$EXCLUDEFNAME"

información relacionada