Tengo una lista de archivos que quiero verificar si existen en mi sistema de archivos. Pensé en hacer esto usando findcomo en:
for f in $(cat file_list); do
find . -name $f > /dev/null || print $f
done
(usando zsh) pero eso no funciona ya que findparece salir 0si encuentra o no el archivo. Supongo que podría pasarlo por alguna otra prueba, que prueba para ver si findproduce algo (crudo pero efectivo sería reemplazarlo > /dev/nullcon |grep ''), pero esto se siente como usar un troll para atrapar una cabra (otras nacionalidades podrían decir algo sobre mazos y nueces )
¿Hay alguna manera de findobligarme a darme un valor de salida útil? ¿O al menos para obtener una lista de esos archivos que no se encontraron? (Me imagino que esto último es quizás más fácil por alguna astuta elección de conexiones lógicas, pero parece que siempre me atoro cuando trato de resolverlo).
Antecedentes / Motivación: Tengo una copia de seguridad "maestra" y quiero verificar que existan algunos archivos en mi máquina local en mi copia de seguridad maestra antes de eliminarlos (para crear un poco de espacio). Así que hice una lista de los archivos, los sshedité en la máquina maestra, y luego no pude encontrar la mejor manera de encontrar los archivos faltantes.

locate.locateno muestra el estado actual del sistema de archivos, podría ser un día o incluso una semana de antigüedad. Eso es adecuado como base para probar las copias de seguridad.Respuestas:
findconsidera no encontrar nada un caso especial de éxito (no se produjo ningún error). Una forma general de probar si los archivos coinciden con algunosfindcriterios es probar si la salida defindestá vacía. Para una mejor eficiencia cuando hay archivos coincidentes, use-quiten GNU find para que se cierre en la primera coincidencia, ohead(head -c 1si está disponible, de lo contrario, lohead -n 1que es estándar) en otros sistemas para que muera por una tubería rota en lugar de producir una salida larga.En bash ≥4 o zsh, no necesita el
findcomando externo para una simple coincidencia de nombre: puede usar**/$name. Versión bash:Versión de Zsh con un principio similar:
O aquí hay una forma más corta pero más críptica de probar la existencia de un archivo que coincida con un patrón. El calificador global
Nhace que la salida esté vacía si no hay coincidencia,[1]conserva solo la primera coincidencia ye:REPLY=true:cambia cada coincidencia para expandirla en1lugar del nombre del archivo coincidente. Entonces se**/"$name"(Ne:REPLY=true:[1]) falseexpande atrue falsesi hay una coincidencia, o simplemente afalsesi no hay coincidencia.Sería más eficiente combinar todos sus nombres en una sola búsqueda. Si el número de patrones no es demasiado grande para el límite de longitud de su sistema en una línea de comando, puede unir todos los nombres
-o, hacer una solafindllamada y procesar posteriormente la salida. Si ninguno de los nombres contiene metacaracteres de shell (de modo que los nombres también sonfindpatrones), esta es una forma de postprocesar con awk (no probado):Otro enfoque sería usar Perl y
File::Find, lo que facilita la ejecución del código Perl para todos los archivos en un directorio.Un enfoque alternativo es generar una lista de nombres de archivos en ambos lados y trabajar en una comparación de texto. Versión Zsh:
fuente
zshsolución con la**sintaxis. Es una solución muy simple y, si bien puede que no sea la más eficiente en términos de máquina , ¡probablemente sea la más eficiente en términos de que realmente lo recuerde! Además, la primera solución aquí responde a la pregunta real en que se tuercefinden algo donde el código de salida distingue "Tengo una coincidencia" de "No obtuve una coincidencia".Puede usarstatpara determinar si existe un archivo en el sistema de archivos.Debe usar las funciones de shell incorporadas para probar si existen archivos.
La "prueba" es opcional y el script realmente funcionará sin él, pero lo dejé allí para facilitar la lectura.
Editar: si realmente no tiene más opción que trabajar para una lista de nombres de archivo sin rutas, le sugiero que cree una lista de archivos una vez con find, luego repítala con grep para descubrir qué archivos hay.
Tenga en cuenta que:
fuente
Un primer enfoque simplista podría ser:
a) ordenar su lista de archivos:
para encontrar faltas, o
para encontrar coincidencias
Inconvenientes:
find podría buscar varios archivos a la vez, con cierta preparación:
find -name a.file -or -name -b.file -or -name c.file ...
¿Podría ser una opción? Una vez más, se supone una lista clasificada de archivos:
Una búsqueda de foo.bar no coincidirá con un archivo foo.ba u oo.bar con --regexp-construct (no debe ser confundido por regex sin p).
Puede especificar una base de datos específica para localizar, y debe actualizarla antes de buscar, si necesita los resultados más recientes.
fuente
Creo que esto también puede ser útil.
Esta es una solución de una línea, en caso de que opte por que su "lista" sea archivos reales que desea sincronizar con otra carpeta:
para ayudar a leer:
este ejemplo excluye los archivos de respaldo "* ~" y limita el tipo de archivo normal "-type f"
fuente
¿Tal vez?
fuente
¿Por qué no simplemente comparar la longitud de la lista de consultas con la longitud de la lista de resultados?
fuente