¿Cómo puedo enumerar archivos de los que no existen enlaces simbólicos?


10

Tengo un gran directorio "myfiles" lleno de documentos misceláneos y no quiero modificar su estructura.

Por lo tanto, creé (varios) otros directorios para cada clase de documentos. Por ejemplo, tengo un directorio de "imágenes" que tiene enlaces simbólicos a cada uno .jpgo un .cr2archivo en el directorio "myfiles" más otros archivos descriptivos para cada enlace simbólico (con el mismo nombre de archivo) con descripción y otros metadatos. Los enlaces simbólicos en el directorio / images pueden tener un nombre diferente del archivo vinculado original.

Estoy tratando de encontrar la forma más sencilla de asegurarme de que todos y cada uno de los archivos de imagen en el directorio "myfiles" tengan un enlace simbólico en el directorio "images".

Vea un ejemplo de la estructura de carpetas

/myfiles/a.doc
/myfiles/b.jpg
/myfiles/c.cr2
/myfiles/d.mov

debería resultar

/images/b_800x600.jpg
/images/b_800x600.desc
/images/c_3820x5640.cr2
/images/c_3820x5640.cr2

No es una respuesta completa, pero podría guardar los resultados de find /myfiles -type fa en un archivo y luego usarlos find /images -type l -exec readlink {} \; | egrep myfilespara obtener una lista de archivos que están enlazados y /imagesluego iterar sobre los resultados haciendo un seden cada uno para eliminar las rutas en el primer archivo que guarda ya que ya tienen el enlace simbólico y los archivos que quedan son los archivos que no tienen el enlace simbólico.
Bratchley

2
¿Es posible que use enlaces duros en su lugar, para que pueda usar el contador de enlaces duros para ver si tiene enlaces? Utilizando ls -lpuede ver el recuento de enlaces en la segunda columna.
Lambert

Haz lo que @Lambert dice. rmesos directorios de enlaces simbólicos y úselos, pax -rwl -s "\|.*regex|modifes_filename|" /path/to/myfiles/*.jpg /path/to/jpg_dirpor ejemplo, para obtener enlaces duros con nombres de archivo alterados programáticamente solo para aquellos archivos que coinciden con sus archivos jpgs. Puede obtener mucho más que eso, como lotes basados ​​en tiempos de cambio, etc.
mikeserv

Respuestas:


6

Si entiendo la pregunta correctamente, necesita archivos en myfiles que no tengan enlaces simbólicos en las imágenes:

#!/bin/bash

OIFS="$IFS"
IFS=$'\n'

files="$(find myfiles/ -type f -name '*.jpg' -or -name '*.cr2')"
for f in $files; do
    list="$(find -L images/ -xtype l -samefile "$f")"
    if [[ "$list" == "" ]]; then
        echo "$f does not have symlink."
    fi
done

IFS="$OIFS"

Hay una advertencia con este enfoque si tiene el archivo a.jpg en el directorio myfiles / 1 y tiene un enlace simbólico a ese archivo en el directorio images / 3 o simplemente en images / el archivo no se informará con el enlace simbólico faltante.


Gracias ! Sí, lo entendiste correctamente. Cerca pero no del todo. Mi culpa no es tuya :-) El ejemplo que di muestra un directorio simplista de mis archivos. En realidad, los archivos de imagen bajo myfiles pueden estar dentro de cualquier nivel arbitrario de directorios anidados.
Robert Alexander

Edité la respuesta para buscar en todos mis archivos, pero compruebe si esto es lo que desea.
taliezin

Casi allí :-) Su script tiene problemas cuando los archivos tienen espacios (y tal vez otra basura, como los apóstrofes individuales "en ellos ..."
Robert Alexander

Creo que ahora debería estar bien
taliezin

¡Su última modificación divide cada f en la aparición de cada letra n! :-) Cambié la línea de IFS a IFS = luego una nueva línea desde el teclado y luego otra ". Ahora la división parece funcionar pero obtengo una secuencia larga de" missinglinks.sh: 11: missinglinks.sh: [[: no encontrado "
Robert Alexander

3

Supongo que los archivos debajo myfilesno son enlaces simbólicos, y que ninguno de los nombres de archivo contiene nuevas líneas. (Mi enfoque aún puede funcionar si se violan estas suposiciones, pero se vuelve más complicado). También supongo que tiene la readlinkutilidad común y que es compatible -fcon la canonización de rutas, que es el caso en Linux (tanto GNU como BusyBox), pero no en, por ejemplo, OSX.

Cree una lista de archivos y ordénela por si acaso:

find /myfiles -type f -print | sort >all.list

Cree una lista de destinos de enlaces simbólicos, con rutas absolutas.

find /images -type f -exec readlink -f {} \; | sort >linked.list

Enumere los archivos que no están vinculados:

comm -32 all.list linked.list

Si usa un shell que admite la sustitución de procesos, puede ponerlo todo en un comando:

comm -23 <(find /myfiles -type f -print | sort) \
         <(find /images -type f -exec readlink -f {} \; | sort)

Si los enlaces debajo /imagesson absolutos, puede usarlos readlinksin la -fopción, que está disponible en * BSD y OSX.


Estaba a punto de publicar algo como su commcomando, pero no lo haré ahora que veo que ya lo hizo. Sin embargo, la redirección de sortno tiene sentido; entonces las sustituciones del proceso no generarán nada. Además, puede agregar muchos directorios al lado /imagessi desea buscar archivos en los /myfilesque no se vinculen los enlaces simbólicos de cualquiera de varios directorios además /images.
tripleee

1
Ver stackoverflow.com/questions/7665/… para alternativas areadlink -f
tripleee

@tripleee Olvidé eliminar la redirección cuando construí la versión de redirección de proceso, gracias. Sí, puede agregar fácilmente otros directorios o hacer otras variaciones.
Gilles 'SO- deja de ser malvado'
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.