¿Cómo hago para que find siga la mayoría, pero no todos, los enlaces simbólicos?

10

Mi sistema operativo y mi directorio personal están en una SSD. Guardo algunos archivos grandes en un disco duro y hago un enlace simbólico desde mi directorio de inicio al disco duro (por ejemplo, ~ / Videos / Films es un enlace simbólico a / mnt / hdd / Films). También tengo varios prefijos de Wine, cada uno de los cuales tiene dosdevices / z: enlazados a /.

Entonces, si usé find sin -L, se perderá todo lo que está en el disco duro. Pero si uso find con -L, termina en un bucle debido al enlace simbólico de Wine a /.

¿Hay alguna forma sensata de resolver esto, de modo que encuentre búsquedas donde quiero que lo haga? Intuitivamente, quiero algo parecido a "seguir enlaces simbólicos, a menos que estén en un directorio llamado dosdevices". "Seguir enlaces simbólicos que son de algo en el disco duro" también funcionaría.

Mark Raymond
fuente

Respuestas:

11

El -pruneprimario le dice que findno se repita bajo un directorio.

find -L -path ~/.wine/dosdevices -prune -o -type f -name 'My Favorite Movie.*' -print

Si desea usar -lnameen su condición, no puede usar la -Lopción, porque -Lhace que la mayoría de los predicados actúen sobre el objetivo del enlace, incluido -lname. Mi recomendación en ese caso sería utilizar tanto su directorio de inicio como la raíz del disco duro como raíces de su búsqueda.

find ~ /mnt/hdd -xtype f -name 'My Favorite Movie.*'

Puede ejecutar find ~ -type l …para recopilar una lista de enlaces simbólicos y utilizarlos como raíces adicionales.

( IFS=$'\n'; set -f;
  find ~ $(find ~ -type l -lname '/mnt/hdd/*') \
       -xtype f -name 'My Favorite Movie.*' )

Si realmente desea volver a aparecer bajo enlaces simbólicos, puede excluir enlaces simbólicos específicos por destino en lugar de por nombre. Sin embargo, solo puede excluir una lista finita, no un patrón o subárbol de esta manera.

find -L \( -samefile /exclude/this -o -samefile ~/and/that \) -prune -o \
     -type f -name 'My Favorite Movie.*' -print

Puede usar otros criterios como ! -writable(archivos para los que no tiene permiso de escritura), pero no creo que GNU find tenga una forma de recurrir bajo enlaces simbólicos solo si su texto de destino coincide con una determinada expresión.

Puede crear un findcomando que haga casi lo que desea, excepto no excluir suficientes enlaces simbólicos, ejecutar find2perl para convertir la consulta en un script Perl y ajustar un poco el script Perl. Sin embargo, hay muchos interruptores de GNU que find2perl no reconoce.

Gilles 'SO- deja de ser malvado'
fuente
¡Gracias! -prunees justo el tipo de cosas que estaba buscando. He encontrado que find ~ \( -lname ~ -o -lname ~/\* -o -lname / \) -xtype denumera todos los enlaces simbólicos que no quiero seguir; Ahora estoy tratando de encontrar una manera de usar esa consulta para podar.
Mark Raymond el
@MarkRaymond El principio general es find ~ <negative criteria> -prune -o <positive criteria> -print, entoncesfind ~ \( -lname ~ -o -lname ~/\* -o -lname / \) -xtype d -prune -o <whatever it is you want> -print
Gilles 'SO- deja de ser malvado' el
@Giles: eso funciona bien sin -L, pero una vez que agrego -L, las expresiones -lname ya no funcionan (como dice la página del manual, no lo harán). ¡Entonces, básicamente, necesito algunas condiciones para seguir enlaces simbólicos y otras no!
Mark Raymond el
No puedo pensar en una forma de hacer exactamente lo que quieres con find. Vea mi edición para algunas aproximaciones.
Gilles 'SO- deja de ser malvado'
1

Para buscar TODOS los enlaces, esto funcionó para mí:

find -L . -name \*.txt
jim
fuente
0

¿Cuántos enlaces simbólicos a discos duros tiene? Si no es demasiada, una solución es no usar "-L" mientras especifica explícitamente los enlaces simbólicos que desea seguir en la línea de comando de búsqueda. Algo como:

find .  ~/Videos/Films -name '*file I want*' ...

Esto buscará el directorio actual (".") Así como el enlace simbólico "~ / Videos / Films" pero no descenderá a otros enlaces simbólicos.

John1024
fuente
0

Otra solución que evita el problema (al menos para mi caso) es usar montajes de enlace en lugar de enlaces simbólicos para los directorios en el disco duro. Esto se hace agregando entradas de /etc/fstabesta manera:

/mnt/hdd/Films /home/mark/Videos/Films none bind 0 0

Mark Raymond
fuente