Estoy buscando un shell de una línea para encontrar el archivo más antiguo en un árbol de directorios.
72
Esto funciona (actualizado para incorporar la sugerencia de Daniel Andersson):
find -type f -printf '%T+ %p\n' | sort | head -n 1
find -type f -printf '%T+ %p\n' | sort | head -1
find
está vacía debido al hecho de que el nombre del archivo contiene nueva línea.Este es un poco más portátil y porque no depende de la
find
extensión GNU-printf
, por lo que también funciona en BSD / OS X:El único inconveniente aquí es que está algo limitado al tamaño de
ARG_MAX
(que debería ser irrelevante para la mayoría de los núcleos más nuevos). Entonces, si hay más degetconf ARG_MAX
caracteres devueltos (262,144 en mi sistema), no le da el resultado correcto. Tampoco es compatible con POSIX porque-print0
yxargs -0
no lo es.Aquí se describen algunas soluciones más para este problema: ¿Cómo puedo encontrar el archivo más reciente (más nuevo, más antiguo, más antiguo) en un directorio? - Wiki de Greg
fuente
xargs: ls: terminated by signal 13
error como efecto secundario. Supongo que es SIGPIPE. No tengo idea de por qué no obtengo un error similar cuando canalizo la salida del tipo a la cabeza en mi solución.head
creo que es el comando que se cierra una vez que ha leído una línea y "rompe" la tubería. No obtiene el error porquesort
no parece quejarse de ello, perols
sí en el otro caso.xargs
necesitan invocarls
más de una vez. En ese caso, los resultados ordenados de esas invocaciones múltiples terminan concatenados cuando deberían fusionarse.ls
verlo y mirar el archivo más antiguo, su solución probablemente superará el límite de longitud de la línea de comando, provocandols
que se invoque varias veces. Obtendrá la respuesta incorrecta, pero nunca lo sabrá.Los siguientes comandos están garantizados para funcionar con cualquier tipo de nombre de archivo extraño:
El uso de un byte nulo (
\0
) en lugar de un carácter de salto de línea (\n
) asegura que la salida de find seguirá siendo comprensible en caso de que uno de los nombres de archivo contenga un carácter de salto de línea.El
-z
conmutador hace que tanto sort como grep interpreten solo bytes nulos como caracteres de fin de línea. Como no hay tal interruptor para la cabeza, usamos en sugrep -m 1
lugar (solo una ocurrencia).Los comandos están ordenados por tiempo de ejecución (medido en mi máquina).
El primer comando será el más lento, ya que primero tiene que convertir el mtime de cada archivo en un formato legible por humanos y luego ordenar esas cadenas. La tubería al gato evita colorear la salida.
El segundo comando es un poco más rápido. Si bien todavía realiza la conversión de fecha, la ordenación numérica (
sort -n
) de los segundos transcurridos desde la época de Unix es un poco más rápida. sed elimina los segundos desde la época de Unix.El último comando no realiza ninguna conversión y debería ser significativamente más rápido que los dos primeros. El comando find en sí no mostrará el tiempo m del archivo más antiguo, por lo que se necesita stat.
Páginas man relacionadas: find - grep - sed - sort - stat
fuente
Aunque la respuesta aceptada y otros aquí hacen el trabajo, si tiene un árbol muy grande, todos ellos ordenarán todo el conjunto de archivos.
Mejor sería si pudiéramos enumerarlos y hacer un seguimiento de los más antiguos, sin la necesidad de ordenarlos.
Por eso se me ocurrió esta solución alternativa:
Espero que pueda ser de ayuda, incluso si la pregunta es un poco vieja.
Edición 1: estos cambios permiten analizar archivos y directorios con espacios. Es lo suficientemente rápido como para emitirlo en la raíz
/
y encontrar el archivo más antiguo.Comando explicado:
Ejecutándolo:
EDITAR 2: Mismo concepto, mejor solución
find
para mirar el tiempo de acceso (use%T
con el primeroprintf
para el tiempo de modificación o%C
para el cambio de estado ).EDITAR 3: el siguiente comando utiliza el tiempo de modificación y también imprime el progreso incremental a medida que encuentra archivos antiguos y antiguos, lo cual es útil cuando tiene algunas marcas de tiempo incorrectas (como 1970-01-01):
fuente
ls
es malo para las secuencias de comandos, ya que su salida no está destinada a máquinas, el formato de salida varía según las implementaciones. Como ya dijiste,find
es bueno para las secuencias de comandos, pero también podría ser bueno agregar esa información antes de contar lasls
soluciones.Utilice ls: la página de manual le indica cómo ordenar el directorio.
El -n 2 es para que no obtenga el "total" en la salida. Si solo quieres el nombre del archivo.
Y si necesita la lista en el orden normal (obtener el archivo más reciente)
Mucho más fácil que usar find, mucho más rápido y más robusto: no tiene que preocuparse por los formatos de nombres de archivos. También debería funcionar en casi todos los sistemas.
fuente
fuente
sort -n
.Parece que por "más viejo" la mayoría de la gente ha asumido que se refería al "tiempo de modificación más antiguo". Probablemente se haya corregido, de acuerdo con la interpretación más estricta de "más antiguo", pero en caso de que desee el que tenga el tiempo de acceso más antiguo , modificaría la mejor respuesta de esta manera:
Note el
%A+
.fuente
find ./search/dirname -type f -printf '%T+ %h/%f\n'
Imprime fechas y nombres de archivos en dos columnas.sort | head -n1
mantiene la línea correspondiente al archivo más antiguo.echo $2
muestra la segunda columna, es decir, el nombre del archivo.fuente