Buscar archivos en el orden de la marca de tiempo

Buscar archivos en el orden de la marca de tiempo

dirTiene dos archivos regulares.

file1tiene abc\n, file2tiene def\n. Comprima estos dos archivos con gzip, como se muestra a continuación,

#ls
#echo 'abc\n' > file1
#echo 'def\n' > file2
#gzip file1
#gzip file2
#ls
file1.gz  file2.gz

Después de leer el contenido,

#find . -type f  -name "*.gz" -exec zgrep -Iq . \{} \; -exec zcat \{} \;
def\n
abc\n

No obtengo el contenido de los archivos en orden de tiempo de creación del archivo. El resultado esperado debe ser siempre abc\ndef\n.

Observación interesante: la producción real es en algún momento, def\nabc\ny a vecesabc\ndef\n

Pregunta:

¿Cómo encontrar archivos en orden (decreciente/aumentando) de marca de tiempo?

Respuesta1

El orden de los archivos informados por findes opaco para el usuario. Puede ser el orden en que aparecen en el directorio. Algunas findimplementaciones los reordenan por número de inodo u otros criterios en un intento de mejorar el rendimiento. La única forma en que uno puede alterar el orden es a través del -depthpredicado que indica findque el proceso/salida salga antes de la rama en la que se encuentran.

Como alternativa a find, puedes usar zshla función global recursiva de :

zgrep whatever ./**/*.gz(D.Om)

El Omcalificador global es ordenar por hora de la última modificación (el más antiguo primero). .es solo para archivos normales (equivalente a find's -type f), Ddebe incluir archivos ocultos (puntos) como findlo haría de forma predeterminada.

Si obtienes unlista de argumentos demasiado largaerror, puedes usar zargs:

autoload -U zargs # best in ~/.zshrc
zargs ./**/*.gz(D.Om) -- zgrep whatever

Con bash(o cualquier shell que admita la sustitución de procesos estilo Ksh) y herramientas GNU recientes, un equivalente sería:

xargs -r0a <(
  export LC_ALL=C
  find . -type f -name '*.gz' -printf '%T@\t%p\0' |
    sort -zn | cut -zf2-) zgrep whatever

Respuesta2

Una opción es generar la marca de tiempo del archivo junto con la ruta del archivo, ordenarla y luego eliminarla:

find -type f -name "*.gz" -printf '%C@\t%p\n'|sort -nk1|cut -f2-|xargs zcat 

Tenga en cuenta que si sus nombres de archivos pueden contener caracteres potencialmente inseguros (como espacios), simplemente reemplace

xargs zcat 

con

xargs -d "\n" zcat 

y si necesita acomodar las nuevas líneas en los nombres de archivos, puede usar un byte nulo para terminar registros, como se detalla en la respuesta de @stéphane-chazelas (esto rara vez es un problema en la práctica).

Respuesta3

Desafortunadamente, el comando de búsqueda funciona de tal manera que no se garantiza que la salida esté en orden alfabético o de antigüedad del archivo. Podrías intentar algo como:

ls -1dtr $(find . -maxdepth 1 -type f -name '*.gz') | xargs gzcat $1

información relacionada