dir
Tiene dos archivos regulares.
file1
tiene abc\n
, file2
tiene 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\n
y 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 find
es opaco para el usuario. Puede ser el orden en que aparecen en el directorio. Algunas find
implementaciones 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 -depth
predicado que indica find
que el proceso/salida salga antes de la rama en la que se encuentran.
Como alternativa a find
, puedes usar zsh
la función global recursiva de :
zgrep whatever ./**/*.gz(D.Om)
El Om
calificador 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
), D
debe incluir archivos ocultos (puntos) como find
lo 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