Si quiero encontrar el último archivo (mtime) en un directorio (grande) que contenga subdirectorios, ¿cómo lo haría?
Muchas publicaciones que he encontrado sugieren alguna variación de ls -lt | head
(de manera divertida, muchas sugieren ls -ltr | tail
cuál es el mismo pero menos eficiente) lo cual está bien a menos que tenga subdirectorios (yo sí).
Por otra parte, podrías
find . -type f -exec ls -lt \{\} \+ | head
lo que definitivamente hará el truco para tantos archivos como pueda especificar un comando, es decir, si tiene un directorio grande , -exec...\+
emitirá comandos separados; por lo tanto, cada grupo se ordenará por ls
sí mismo pero no por encima del conjunto total; Por lo tanto, la cabeza recogerá la última entrada del primer lote.
Alguna respuesta?
command-line
find
Rico
fuente
fuente
find: missing argument to '-exec'
+
no tiene ningún significadobash
, por lo que no es necesario escapar.Respuestas:
No necesita recurrir a comandos externos (as
ls
) porquefind
puede hacer todo lo que necesita a través de la-printf
acción:fuente
find . -type f -exec stat --format=%y \{\} \+ | sort -r | head -n1
pero su solución es mucho más limpia!| cut -d ' ' -f2
para obtener solo el nombre del archivohead
para incluir un cierto número de líneas. Solo necesitaba la primera línea, así que uséhead -n 1
Tuve un problema similar hoy, pero lo ataqué sin él
find
. Necesitaba algo breve que pudiera atropellarssh
para devolver el archivo editado más recientemente en mi directorio de inicio. Esto es más o menos lo que se me ocurrió:La
-p
opción parals
agregar una barra inclinada final a los directorios,grep -v
elimina las líneas que terminan en una barra inclinada (también conocido como todos los directorios) yhead -1
limita la salida a un solo archivo.Esto es mucho menos detallado que usar
find
si todo lo que desea devolver es el nombre del archivo.fuente
Esto está en mi sistema más rápido que
printf
, aunque no entiendo por quéfuente
... | sort -r | head -n1 | cut -d " " -f 4-
si desea obtener solo el nombre del archivo.sort -r
será incorrecto si existe un nombre de archivo en varias líneas.EDITAR: Supongo que esta publicación no es "no particularmente útil" como pensé que era. Esta es una solución realmente rápida que solo realiza un seguimiento del archivo modificado más recientemente (en lugar de ordenar la lista completa de archivos):
find . -type f -printf '%T@ %p\n' | awk 'BEGIN { mostrecenttime = 0; mostrecentline = "nothing"; } { if ($1 > mostrecenttime) { mostrecenttime = $1; mostrecentline = $0; } } END { print mostrecentline; }' | cut -f2- -d ' '
Repartidas en varias líneas para mayor claridad, se ve de la siguiente manera:
Fin de EDITAR
No es una publicación particularmente útil, pero dado que 'organizar' estaba discutiendo la velocidad, pensé en compartir esto.
Las soluciones del arreglo y enzotib implican enumerar todos los archivos dentro del directorio con sus mtimes y luego ordenarlos. Como sabes, no es necesario ordenar para encontrar el máximo. Encontrar el máximo se puede hacer en tiempo lineal, pero la clasificación lleva n tiempo log (n) [Sé que la diferencia no es mucha, pero aún así;]]. No puedo pensar en una forma ordenada de implementar esto. [EDITAR: Una implementación ordenada (aunque sucia) y rápida proporcionada anteriormente.]
Siguiente mejor opción: para buscar el archivo editado más recientemente en un directorio, busque recursivamente el archivo editado más recientemente en cada subdirectorio de nivel 1. Deje que este archivo represente el subdirectorio. Ahora ordene los archivos de nivel 1 junto con los representantes de los subdirectorios de nivel 1. Si el número de archivos de nivel 1 y subdirectorios de cada directorio es casi constante, entonces este proceso debería escalar linealmente con el número total de archivos.
Esto es lo que se me ocurrió para implementar esto:
Ejecuté esto y obtuve un montón de
find: findrecent: No such file or directory
errores. Motivo: -exec de find se ejecuta en un shell diferente. Traté de definir findrecent en .bashrc, .xsessionrc pero esto no ayudó [agradecería la ayuda aquí]. Al final recurrí a poneren un script llamado
findrecent
en mi RUTA y luego ejecutarlo.Ejecuté esto, seguí esperando y esperando sin salida. Solo para asegurarme de que no estaba lidiando con ningún bucle infinito, modifiqué el archivo a
e intenté de nuevo. Funcionó, pero tardó 1 minuto y 35 segundos en mi carpeta personal, ¡las soluciones de Arreglo y enzotib tomaron 1.69, 1.95 segundos respectivamente!
¡Tanto por la superioridad de O (n) sobre O (n log (n))! ¡Maldita sea tu función, llamada sobrecarga! [O más bien, sobrecarga de llamadas de script]
Pero este script escala mejor que las soluciones anteriores y apuesto a que se ejecutará más rápido que ellos en el banco de memoria de Google; D
fuente
Usar
perl
en conjonctina confind
:Obtiene el nombre del archivo con la mayor época == último archivo modificado.
fuente
No está tan de moda, pero también es posible lograrlo con Midnight Commander : busque *, panelice el resultado, ordene por tiempo de modificación en orden inverso.
Obviamente, es un poco más lento que
find
: mi directorio de inicio, que contiene 922000 archivos, se ordenómc
en casi 14 minutos, mientras quefind
pasé menos de 5, pero hay algunos beneficios:Probablemente pasaría más tiempo que la diferencia de 9 minutos inventando una invocación de búsqueda adecuada :)
menos posibilidades de error (olvidé especificar -r para ordenar, etc., comience de nuevo)
es posible jugar con el conjunto de resultados cambiando el orden de clasificación, etc., sin volver a consultar los archivos.
es posible realizar operaciones de archivo solo en algunos archivos del conjunto de resultados, es decir, ordenar por tamaño, eliminar algunos archivos grandes que no son necesarios
fuente