ver ultimos por modificados modificacion listar fecha extension creados carpeta buscar archivos archivo linux recursion time filesystems

por - listar ultimos archivos modificados linux



¿Cómo encontrar y listar recursivamente los últimos archivos modificados en un directorio con subdirectorios y tiempos? (16)

  • Sistema operativo: Linux

  • Tipo de sistema de archivos: ext3

  • Solución preferida: bash (script / oneliner), ruby, python

Tengo varios directorios con varios subdirectorios y archivos en ellos. Necesito hacer una lista de todos estos directorios que se construye de tal manera que cada directorio de primer nivel se encuentre junto a la fecha y hora del último archivo creado / modificado dentro de él.

Para aclarar, si toco un archivo o modifico su contenido a unos pocos niveles de subdirectorio hacia abajo, esa marca de tiempo debe aparecer junto al nombre del directorio de primer nivel. Digamos que tengo un directorio estructurado como este:

./alfa/beta/gamma/example.txt

y modifico el contenido del archivo example.txt , necesito que la hora se muestre junto al directorio alfa primer nivel en forma legible para los humanos, no en la época. He intentado algunas cosas utilizando find, xargs , sort y likes, pero no puedo solucionar el problema de que la marca de tiempo del sistema de archivos de ''alfa'' no cambia cuando creo / modifico los archivos unos niveles más abajo.


Ignorando archivos ocultos - con sello de tiempo agradable y rápido

Maneja bien los espacios en los nombres de archivo, ¡no es que debas usarlos!

$ find . -type f -not -path ''*//.*'' -printf ''%TY.%Tm.%Td %THh%TM %Ta %p/n'' |sort -nr |head -n 10 2017.01.28 07h00 Sat ./recent 2017.01.21 10h49 Sat ./hgb 2017.01.16 07h44 Mon ./swx 2017.01.10 18h24 Tue ./update-stations 2017.01.09 10h38 Mon ./stations.json

Más find abundancia se puede encontrar siguiendo el enlace.


Acorté la asombrosa respuesta de Halo a esta frase única.

stat --printf="%y %n/n" $(ls -tr $(find * -type f))

Actualizado : si hay espacios en los nombres de archivo, puede utilizar esta modificación

OFS="$IFS";IFS=$''/n'';stat --printf="%y %n/n" $(ls -tr $(find . -type f));IFS="$OFS";


Aquí hay una versión que funciona con nombres de archivos que pueden contener espacios, nuevas líneas y también caracteres globales:

find . -type f -printf "%T@ %p/0" | sort -zk1nr

  • find ... -printf imprime la modificación del archivo (valor EPOCH) seguido de un espacio y /0 nombres de archivo terminados.
  • sort -zk1nr lee los datos terminados en NUL y los ordena en orden numérico inverso

Como la pregunta está etiquetada con Linux, supongo que los gnu utils están disponibles.

Puedes canalizar arriba con:

xargs -0 printf "%s/n"

para imprimir la hora de modificación y los nombres de archivo ordenados por la hora de modificación (la más reciente primero) terminada por líneas nuevas.


Este comando funciona en Mac OS X:

find "$1" -type f -print0 | xargs -0 stat --format ''%Y :%y %n'' | sort -nr | cut -d: -f2- | head

En Linux, como pidió el póster original, use stat lugar de gstat .

Esta respuesta es, por supuesto, la solución sobresaliente del user37078 , promovida del comentario a la respuesta completa. CharlesB la idea de gstat utilizar gstat en Mac OS X. Por gstat , obtuve coreutils de MacPorts lugar de homebrew .

Y aquí es cómo empaqueté esto en un comando simple ~/bin/ls-recent.sh para reutilizarlo:

#!/bin/bash # ls-recent: list files in a dir tree, most recently modified first # # Usage: ls-recent path [-10 | more] # # Where "path" is a path to target directory, "-10" is any arg to pass # to "head" to limit the number of entries, and "more" is a special arg # in place of "-10" which calls the pager "more" instead of "head". if [ "more" = "$2" ]; then H=more; N='''' else H=head; N=$2 fi find "$1" -type f -print0 |xargs -0 gstat --format ''%Y :%y %n'' / |sort -nr |cut -d: -f2- |$H $N


Esto podría hacerse con una función reccursiva en bash también

Sea F una función que muestra la hora del archivo que debe ser lexicográficamente clasificable aaaa-mm-dd, etc. (¿dependiente del sistema?)

F(){ stat --format %y "$1";} # Linux F(){ ls -E "$1"|awk ''{print$6" "$7}'';} # SunOS: maybe this could be done easier

R la función recursiva que se ejecuta a través de directorios

R(){ local f;for f in "$1"/*;do [ -d "$f" ]&&R $f||F "$f";done;}

Y finalmente

for f in *;do [ -d "$f" ]&&echo `R "$f"|sort|tail -1`" $f";done


Estoy mostrando esto para el último tiempo de acceso, puede modificarlo fácilmente para hacer el último tiempo de modificación.

Hay dos maneras de hacer esto:

1) Si desea evitar la clasificación global, que puede ser costosa si tiene decenas de millones de archivos, entonces puede hacerlo: (colóquese en la raíz del directorio donde desea que comience la búsqueda)

linux> touch -d @0 /tmp/a; linux> find . -type f -exec tcsh -f -c test `stat --printf="%X" {}` -gt `stat --printf="%X" /tmp/a` ; -exec tcsh -f -c touch -a -r {} /tmp/a ; -print

El método anterior imprime los nombres de archivo con un tiempo de acceso progresivamente más nuevo y el último archivo que se imprime es el archivo con el último tiempo de acceso. Obviamente, puede obtener el último tiempo de acceso utilizando una "cola -1".

2) Puede hacer que encuentre de forma recursiva el nombre, el tiempo de acceso de todos los archivos en su subdirectorio y luego ordene según el tiempo de acceso y la cola la entrada más grande:

linux> /find . -type f -exec stat --printf="%X %n/n" {} /; | /sort -n | tail -1

Y ahí lo tienes...


Función bash rápida:

# findLatestModifiedFiles(directory, [max=10, [format="%Td %Tb %TY, %TT"]]) function findLatestModifiedFiles() { local d="${1:-.}" local m="${2:-10}" local f="${3:-%Td %Tb %TY, %TT}" find "$d" -type f -printf "%T@ :$f %p/n" | sort -nr | cut -d: -f2- | head -n"$m" }

Encuentra el último archivo modificado en un directorio:

findLatestModifiedFiles "/home/jason/" 1

También puede especificar su propio formato de fecha / hora como tercer argumento.


GNU Find (ver man find ) tiene un parámetro -printf para mostrar los archivos EPOC mtime y el nombre de ruta relativo.

redhat> find . -type f -printf ''%T@ %P/n'' | sort -n | awk ''{print $2}''


Lo siguiente le devuelve una cadena de la marca de tiempo y el nombre del archivo con la marca de tiempo más reciente:

find $Directory -type f -printf "%TY-%Tm-%Td-%TH-%TM-%TS %p/n" | sed -r ''s/([[:digit:]]{2})/.([[:digit:]]{2,})//1-/2/'' | sort --field-separator=''-'' -nrk1 -nrk2 -nrk3 -nrk4 -nrk5 -nrk6 -nrk7 | head -n 1

Resultando en una salida de la forma: <yy-mm-dd-hh-mm-ss.nanosec> <filename>


Para encontrar todos los archivos en los que se modificó el estado del archivo hace N minutos:

find -cmin -N

por ejemplo:

find -cmin -5


Para una salida ls simple, usa esto. No hay lista de argumentos, por lo que no puede ser demasiado larga:

find . | while read FILE;do ls -d -l "$FILE";done

Y agradable con cut solo para las fechas, horas y nombre:

find . | while read FILE;do ls -d -l "$FILE";done | cut --complement -d '' '' -f 1-5

EDITAR : acaba de notar que la respuesta principal actual se ordena por fecha de modificación. Eso es igual de fácil con el segundo ejemplo aquí, ya que la fecha de modificación es la primera en cada línea; dé una palmada al final:

find . | while read FILE;do ls -d -l "$FILE";done | cut --complement -d '' '' -f 1-5 | sort


Prueba este:

#!/bin/bash find $1 -type f -exec stat --format ''%Y :%y %n'' "{}" /; | sort -nr | cut -d: -f2- | head

Ejecútelo con la ruta al directorio donde debería comenzar a escanear recursivamente (admite nombres de archivo con espacios).

Si hay muchos archivos, puede tomar un tiempo antes de que devuelva algo. El rendimiento puede mejorarse si usamos xargs lugar:

#!/bin/bash find $1 -type f -print0 | xargs -0 stat --format ''%Y :%y %n'' | sort -nr | cut -d: -f2- | head

que es un poco más rápido.


Prueba esto

#!/bin/bash stat --format %y $(ls -t $(find alfa/ -type f) | head -n 1)

Utiliza la función find para recopilar todos los archivos del directorio, ls para enumerarlos ordenados por fecha de modificación, head para seleccionar el primer archivo y finalmente stat para mostrar la hora en un formato agradable.

En este momento no es seguro para los archivos con espacios en blanco u otros caracteres especiales en sus nombres. Escribe una recomendación si aún no satisface tus necesidades.


Tanto las soluciones perl como Python en este post me ayudaron a resolver este problema en Mac OS X: https://unix.stackexchange.com/questions/9247/how-to-list-files-sorted-by-modification-date-recursively-no-stat-command-avail .

Citando desde el post:

Perl:

find . -type f -print | perl -l -ne '' $_{$_} = -M; # store file age (mtime - now) END { $,="/n"; print sort {$_{$b} <=> $_{$a}} keys %_; # print by decreasing age }''

Pitón:

find . -type f -print | python -c ''import os, sys; times = {} for f in sys.stdin.readlines(): f = f[0:-1]; times[f] = os.stat(f).st_mtime for f in sorted(times.iterkeys(), key=lambda f:times[f]): print f''


Tengo este alias en mi .profile que uso bastante a menudo

$ alias | grep xlogs xlogs=''sudo find . /( -name "*.log" -o -name "*.trc" /) -mtime -1 | sudo xargs ls -ltr --color | less -R''

Así que hace lo que está buscando (con la excepción de que no se modifica la fecha / hora en varios niveles): busca los archivos más recientes (archivos * .log y * .trc en este caso); También solo encuentra los archivos modificados en el último día, luego ordena por tiempo y canaliza la salida a través de menos:

sudo find . /( -name "*.log" -o -name "*.trc" /) -mtime -1 | sudo xargs ls -ltr --color | less -R

PD. Tenga en cuenta que no tengo root en algunos de los servidores, pero siempre tengo sudo, por lo que es posible que no necesite esa parte.


Usted puede dar el comando printf de encontrar un intento

El último tiempo de acceso de% Ak File en el formato especificado por k, que es @'' or a directive for the C strftime''. Los valores posibles para k se enumeran a continuación; Es posible que algunos de ellos no estén disponibles en todos los sistemas, debido a las diferencias en el "tiempo de respuesta" entre los sistemas.