Lo que me pareció confuso -prune
es que es una acción (como -print
), no una prueba (como -name
). Altera la lista de "tareas", pero siempre devuelve verdadero .
El patrón general para usar -prune
es este:
find [path] [conditions to prune] -prune -o \
[your usual conditions] [actions to perform]
Casi siempre desea el -o
(OR lógico) inmediatamente después -prune
, porque esa primera parte de la prueba (hasta incluir -prune
) devolverá falso para las cosas que realmente desea (es decir, las cosas que no desea eliminar).
Aquí hay un ejemplo:
find . -name .snapshot -prune -o -name '*.foo' -print
Esto encontrará los archivos "* .foo" que no están en los directorios ".snapshot". En este ejemplo, -name .snapshot
constituye el [conditions to prune]
, y -name '*.foo' -print
es [your usual conditions]
y [actions to perform]
.
Notas importantes :
Si todo lo que desea hacer es imprimir los resultados, podría estar acostumbrado a omitir la -print
acción. Generalmente no quieres hacer eso cuando lo usas -prune
.
El comportamiento predeterminado de find es "y" toda la expresión con la -print
acción si no hay otras acciones que -prune
(irónicamente) al final. Eso significa que escribir esto:
find . -name .snapshot -prune -o -name '*.foo' # DON'T DO THIS
es equivalente a escribir esto:
find . \( -name .snapshot -prune -o -name '*.foo' \) -print # DON'T DO THIS
lo que significa que también imprimirá el nombre del directorio que está podando, que generalmente no es lo que desea. En cambio, es mejor especificar explícitamente la -print
acción si eso es lo que quieres:
find . -name .snapshot -prune -o -name '*.foo' -print # DO THIS
Si su "condición habitual" coincide con archivos que también coinciden con su condición de poda, esos archivos no se incluirán en la salida. La forma de solucionar esto es agregar un -type d
predicado a su condición de poda.
Por ejemplo, supongamos que deseamos eliminar cualquier directorio que comenzó con .git
(esto es cierto que está inventado, normalmente solo necesita eliminar la cosa nombrada exactamente .git
), pero aparte de eso desea ver todos los archivos, incluidos los archivos similares .gitignore
. Puedes probar esto:
find . -name '.git*' -prune -o -type f -print # DON'T DO THIS
Esto no incluiría .gitignore
en la salida. Aquí está la versión fija:
find . -name '.git*' -type d -prune -o -type f -print # DO THIS
find
Consejo adicional: si está utilizando la versión GNU de , la página texinfo find
tiene una explicación más detallada que su página de manual (como es cierto para la mayoría de las utilidades GNU).
Laurence Gonsalves
fuente
-prune
no solo funciona en los directorios (sino que, para los directorios, también impide ingresar los directorios que coinciden con esa condición, es decir, aquí los directorios coinciden con eso-name .snapshot
).-prune
cierto, no es en sí mismo lo que causa esto. El problema es que el operador o "cortocircuita", y o tiene menor prioridad que y. El resultado final es que si.snapshot
se encuentra un archivo llamado , coincidirá con el primero-name
,-prune
luego no hará nada (pero devuelve verdadero), y luego el o devuelve verdadero ya que su argumento izquierdo era verdadero. La acción (por ejemplo:)-print
es parte de su segundo argumento, por lo que nunca tiene la oportunidad de ejecutarse.-print
al final, ahora puedo dejar de agregar\! -path <pattern>
además de-prune
Normalmente, la forma nativa en que hacemos las cosas en Linux y la forma en que pensamos es de izquierda a derecha.
Entonces, primero irías y escribirías lo que estás buscando:
Entonces probablemente presionas enter y te das cuenta de que estás obteniendo demasiados archivos de directorios que no deseas. Excluyamos / medios para evitar buscar en sus unidades montadas.
Ahora debería APROBAR lo siguiente al comando anterior:
entonces el comando final es:
............... | <--- Incluir ---> | .................... | <- -------- Excluir ---------> |
Creo que esta estructura es mucho más fácil y se correlaciona con el enfoque correcto.
fuente
find
es lo suficientemente inteligente como para procesar la-prune
cláusula primero. Hmmm, interesante.-prune
partir de ahora./media
, notando que no se llama*.php
y luego comprobando si está actualmente dentro/media
, viendo que sí y, por lo tanto, omitiendo todo el subárbol. Todavía es de izquierda a derecha, simplemente no hace ninguna diferencia siempre que ambas verificaciones no se superpongan.Tenga en cuenta que -prune no impide descender a ningún directorio como algunos han dicho. Impide descender a directorios que coinciden con la prueba a la que se aplica. Quizás algunos ejemplos ayuden (vea la parte inferior para ver un ejemplo de expresiones regulares). Perdón por que esto sea tan largo.
fuente
find . -name test -prune -o -print
: iow,-prune
es una acción que también funciona en archivosAgregando al consejo dado en otras respuestas (no tengo representante para crear respuestas) ...
Cuando se combina
-prune
con otras expresiones, hay una sutil diferencia en el comportamiento dependiendo de qué otras expresiones se usen.El ejemplo de @Laurence Gonsalves encontrará los archivos "* .foo" que no están en los directorios ".snapshot": -
Sin embargo, esta abreviatura ligeramente diferente, quizás inadvertidamente, también
.snapshot
listará el directorio (y cualquier directorio anidado .snapshot):El motivo es (según la página de manual de mi sistema): -
Es decir, el segundo ejemplo es el equivalente a ingresar lo siguiente, modificando así la agrupación de términos:
Esto al menos se ha visto en Solaris 5.10. Después de haber usado varios sabores de * nix durante aproximadamente 10 años, solo recientemente he buscado una razón por la cual esto ocurre.
fuente
-prune
con y sin-print
!La poda es un no recurse en cualquier cambio de directorio.
Desde la página del manual
Básicamente, no desembocará en ningún subdirectorio.
Toma este ejemplo:
Tienes los siguientes directorios
Si corres
find -name test2
:Devolverá ambos directorios
Si corres
find -name test2 -prune
:Solo regresará / home / test2 ya que no descenderá a / home / test2 para encontrar / home / test2 / test2
fuente
No soy un experto en esto (y esta página fue muy útil junto con http://mywiki.wooledge.org/UsingFind )
Recién notado
-path
es para una ruta que coincide completamente con la cadena / ruta que viene justo despuésfind
(.
en estos ejemplos) donde-name
coincide con todos los nombres de base.bloquea el directorio .git en su directorio actual ( como lo encuentra en
.
)bloquea todos los subdirectorios .git de forma recursiva.
Tenga en cuenta que
./
es extremadamente importante !!-path
debe coincidir con un camino anclado.
o lo que sea que venga justo después de encontrar si obtiene coincidencias sin él (desde el otro lado de la o '-o
') ¡probablemente no se poden! Yo ignoraba esto ingenuamente y me puso a usar -path cuando es genial cuando no quieres podar todos los subdirectorios con el mismo nombre base: Dfuente
find bla/
, necesitaría -pathbla/
.git (o si empujó un a*
en el frente, se comportaría más como -name)Mostrar todo, incluido el directorio en sí, pero no sus contenidos aburridos:
fuente
Si lees todas las buenas respuestas aquí, ahora entiendo que lo siguiente devuelve los mismos resultados:
Pero el último tomará mucho más tiempo ya que aún busca todo en dir1. Supongo que la verdadera pregunta es cómo
-or
sacar resultados no deseados sin buscarlos realmente.Así que supongo que podar significa no hacer partidos pasados decentes, sino marcarlo como hecho ...
http://www.gnu.org/software/findutils/manual/html_mono/find.html "Sin embargo, esto no se debe al efecto de la acción '-prune' (que solo evita un mayor descenso, no asegura ignoramos ese elemento). En cambio, este efecto se debe al uso de '-o'. Dado que el lado izquierdo de la condición "o" ha tenido éxito para ./src/emacs, no es necesario evaluar el derecho- lado de la mano ('-print') para este archivo en particular ".
fuente
find
construye una lista de archivos. Aplica el predicado que proporcionó a cada uno y devuelve los que pasan.Esta idea que
-prune
significa excluir de los resultados fue realmente confusa para mí. Puede excluir un archivo sin podar:Todo lo que
-prune
hace es alterar el comportamiento de la búsqueda. Si la coincidencia actual es un directorio, dice "oyefind
, ese archivo que acabas de emparejar, no desciendas en él" . Simplemente elimina ese árbol (pero no el archivo en sí) de la lista de archivos para buscar.Debería ser nombrado
-dont-descend
.fuente
Hay bastantes respuestas; algunos de ellos son demasiado teóricos. Dejaré por qué necesitaba podar una vez, así que tal vez el tipo de explicación de necesidad primero / ejemplo sea útil para alguien :)
Problema
Tenía una carpeta con aproximadamente 20 directorios de nodos, cada uno con su
node_modules
directorio como se esperaba.Una vez que entras en cualquier proyecto, ves cada uno
../node_modules/module
. Pero ya sabes cómo es. Casi todos los módulos tienen dependencias, por lo que lo que estás viendo es más comoprojectN/node_modules/moduleX/node_modules/moduleZ...
No quería ahogarme con una lista con la dependencia de la dependencia de ...
Conocer
-d n
/-depth n
, no me habría ayudado, ya que el directorio main / first node_modules que quería de cada proyecto tenía una profundidad diferente, como esta:¿Cómo puedo obtener una lista de rutas que terminen en la primera
node_modules
y pasar al siguiente proyecto para obtener la misma?Entrar
-prune
Cuando agregue
-prune
, seguirá teniendo una búsqueda recursiva estándar. Se analiza cada "camino", y cada hallazgo se escupe yfind
sigue cavando como un buen muchacho. Pero es la excavación de más denode_modules
lo que no quería.Entonces, la diferencia es que en cualquiera de esos caminos diferentes,
-prune
dejaráfind
de cavar más abajo en esa avenida en particular cuando haya encontrado su artículo. En mi caso, lanode_modules
carpeta.fuente