recursivo recursivamente directorios directorio contar con buscar archivos archivo bash filesystems find

bash - directorios - ¿Cómo encontrar recursivamente el último archivo modificado en un directorio?



contar archivos recursivamente linux (19)

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.25 18h23 Wed ./indenting/Shifting blocks visually.mht 2016.12.11 12h33 Sun ./tabs/Converting tabs to spaces.mht 2016.12.02 01h46 Fri ./advocacy/2016.Vim or Emacs - Which text editor do you prefer?.mht 2016.11.09 17h05 Wed ./Word count - Vim Tips Wiki.mht

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

Parece que ls no ordena los archivos correctamente al hacer una llamada recursiva:

ls -altR . | head -n 3

¿Cómo puedo encontrar el archivo modificado más recientemente en un directorio (incluidos los subdirectorios)?


El siguiente comando funcionó en Solaris:

find . -name "*zip" -type f | xargs ls -ltr | tail -1


En Ubuntu 13, lo siguiente lo hace, tal vez un poco más rápido, ya que invierte el ordenamiento y usa ''cabeza'' en lugar de ''cola'', lo que reduce el trabajo. Para mostrar los 11 archivos más nuevos en un árbol:

encontrar . -tipo f -printf ''% T @% p / n'' | sort -n -r | cabeza -11 | corte -f2- -d "" | sed -e ''s, ^. / ,,'' | xargs ls -U -l

Esto da una lista completa de ls sin reorganizar y omite el molesto ''./'' que ''buscar'' pone en cada nombre de archivo.

O, como una función de bash:

treecent () { local numl if [[ 0 -eq $# ]] ; then numl=11 # Or whatever default you want. else numl=$1 fi find . -type f -printf ''%T@ %p/n'' | sort -n -r | head -${numl} | cut -f2- -d" " | sed -e ''s,^/./,,'' | xargs ls -U -l }

Aún así, la mayor parte del trabajo fue hecho por la solución original de plundra. Gracias plundra


En lugar de ordenar los resultados y conservar solo los últimos modificados, puede usar awk para imprimir solo el que tenga el mayor tiempo de modificación (en tiempo de Unix):

find . -type f -printf "%T@/0%p/0" | awk '' { if ($0>max) { max=$0; getline mostrecent } else getline } END{print mostrecent}'' RS=''/0''

Esta debería ser una forma más rápida de resolver su problema si el número de archivos es lo suficientemente grande.

He usado el carácter NUL (es decir, ''/ 0'') porque, en teoría, un nombre de archivo puede contener cualquier carácter (incluido el espacio y la nueva línea), excepto ese.

Si no tiene dichos nombres de archivo patológicos en su sistema, también puede usar el carácter de nueva línea:

find . -type f -printf "%T@/n%p/n" | awk '' { if ($0>max) { max=$0; getline mostrecent } else getline } END{print mostrecent}'' RS=''/n''

Además, esto funciona también en mawk.


Encontré útil el comando anterior, pero para mi caso necesitaba ver la fecha y la hora del archivo y tuve un problema con varios archivos que tienen espacios en los nombres. Aquí está mi solución de trabajo.

find . -type f -printf ''%T@ %p/n'' | sort -n | tail -1 | cut -f2- -d" " | sed ''s/.*/"&"/'' | xargs ls -l


Encuentro lo siguiente más corto y con más salida interpretable:

find . -type f -printf ''%TF %TT %p/n'' | sort | tail -1

Dada la longitud fija de los tiempos de datos estandarizados del formato ISO, la clasificación lexicográfica está bien y no necesitamos la opción -n en la clasificación.

Si desea eliminar las marcas de tiempo de nuevo, puede utilizar:

find . -type f -printf ''%TFT%TT %p/n'' | sort | tail -1 | cut -f2- -d'' ''


Escribí un paquete pypi / github para esta pregunta porque también necesitaba una solución.

https://github.com/bucknerns/logtail

Instalar:

pip install logtail

Uso: colas archivos cambiados

logtail <log dir> [<glob match: default=*.log>]

Usage2: Abre el último archivo modificado en el editor

editlatest <log dir> [<glob match: default=*.log>]


Este simple cli también funcionará:

ls -1t | head -1

Puede cambiar el -1 al número de archivos que desea enumerar.


Esto cambia de forma recursiva la hora de modificación de todos los directorios en el directorio actual al archivo más nuevo en cada directorio:

for dir in */; do find $dir -type f -printf ''%T@ "%p"/n'' | sort -n | tail -1 | cut -f2- -d" " | xargs -I {} touch -r {} $dir; done


Esto da una lista ordenada:

find . -type f -ls 2>/dev/null | sort -M -k8,10 | head -n5

Invierta el orden colocando una ''-r'' en el comando de ordenación. Si solo desea nombres de archivos, inserte "awk ''{print $ 11}'' |" antes de ''| cabeza''


Esto parece funcionar bien, incluso con subdirectorios:

find . -type f | xargs ls -ltr | tail -n 1

En caso de que haya demasiados archivos, refine el hallazgo.


Me enfrenté al mismo problema. Necesito encontrar el archivo más reciente de forma recursiva. Encontrar tardó alrededor de 50 minutos en encontrar.

Aquí hay un pequeño script para hacerlo más rápido:

#!/bin/sh CURRENT_DIR=''.'' zob () { FILE=$(ls -Art1 ${CURRENT_DIR} | tail -n 1) if [ ! -f ${FILE} ]; then CURRENT_DIR="${CURRENT_DIR}/${FILE}" zob fi echo $FILE exit } zob

Es una función recursiva que obtiene el elemento modificado más reciente de un directorio. Si este elemento es un directorio, la función se llama de forma recursiva y busca en este directorio, etc.


Muestra el último archivo con marca de tiempo legible por humanos:

find . -type f -printf ''%TY-%Tm-%Td %TH:%TM: %Tz %p/n''| sort -n | tail -n1

El resultado se ve así:

2015-10-06 11:30: +0200 ./foo/bar.txt

Para mostrar más archivos, reemplace -n1 con un número mayor


Si ejecutar stat en cada archivo individualmente es lento, puede usar xargs para acelerar un poco las cosas:

find . -type f -print0 | xargs -0 stat -f "%m %N" | sort -n | tail -1 | cut -f2- -d" "


Siguiendo con la respuesta de @plundra , aquí está la versión BSD y OS X:

find . -type f -print0 | xargs -0 stat -f "%m %N" | sort -rn | head -1 | cut -f2- -d" "


Tuve la molestia de encontrar el último archivo modificado en Solaris 10. Allí no tiene la opción printf y stat no está disponible. Descubrí la siguiente solución que me funciona bien:

find . -type f | sed ''s/.*/"&"/'' | xargs ls -E | awk ''{ print $6," ",$7 }'' | sort | tail -1

Para mostrar el nombre de archivo, así como el uso

find . -type f | sed ''s/.*/"&"/'' | xargs ls -E | awk ''{ print $6," ",$7," ",$9 }'' | sort | tail -1

Explicación

  • find . -type f find . -type f encuentra y lista todos los archivos
  • sed ''s/.*/"&"/'' envuelve el nombre de ruta entre comillas para manejar espacios en blanco
  • xargs ls -E envía la ruta citada a ls , la opción -E se asegura de que se devuelva una marca de tiempo completa (formato año-mes-día hora-minuto-segundos-nanosegundos )
  • awk ''{ print $6," ",$7 }'' extrae solo la fecha y la hora
  • awk ''{ print $6," ",$7," ",$9 }'' extrae fecha, hora y nombre de archivo
  • sort devuelve los archivos ordenados por fecha
  • tail -1 devuelve solo el último archivo modificado

Uso algo similar todo el tiempo, así como la lista top-k de los archivos modificados más recientemente. Para grandes árboles de directorios, puede ser mucho más rápido evitar la clasificación . En el caso de solo el archivo top-1 más recientemente modificado:

find . -type f -printf ''%T@ %p/n'' | perl -ne ''@a=split(//s+/, $_, 2); ($t,$f)=@a if $a[0]>$t; print $f if eof()''

En un directorio que contiene 1.7 millones de archivos, recibo el más reciente en 3.4s, una aceleración de 7.5x contra la solución de 25.5s usando ordenación.


Yo prefiero este, es más corto:

find . -type f -print0|xargs -0 ls -drt|tail -n 1


find . -type f -printf ''%T@ %p/n'' | sort -n | tail -1 | cut -f2- -d" "

Para un árbol enorme, puede ser difícil mantener todo en la memoria.

%T@ te da el tiempo de modificación como una marca de tiempo de Unix, sort -n ordena numéricamente, tail -1 toma la última línea (la marca de tiempo más alta), cut -f2 -d" " corta el primer campo (la marca de tiempo) de la salida .

Edición: así como -printf es probablemente solo GNU, el uso de aj-real de stat -c también lo es. Aunque es posible hacer lo mismo en BSD, las opciones para formatear son diferentes (parecería -f "%m %N" )

Y me perdí la parte de plural; Si desea más que el último archivo, simplemente suba el argumento de la cola.