Find files in the order of timestamp

filesfindsorttimestamps

dir has two regular files.

file1 has abc\n, file2 has def\n. Compress these two files with gzip, as shown below,

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

After I cat the content,

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

I do not get the content of files in order of the file creation time.
The expected output should be always abc\ndef\n.

Interesting observation: Actual output is sometime, def\nabc\n and sometimes abc\ndef\n

Question:

How to find files in order(decreasing/increasing) of timestamp?

Best Answer

The order of files reported by find is opaque to the user. It can be the order they appear in the directory. Some find implementations reorder them by inode number or other criteria in an attempt to improve performance. The only way one may alter the order is via the -depth predicate that tells find to process/output leaves before the branch they're on.

As an alternative to find, you could use zsh's recursive glob feature:

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

The Om glob qualifier is to sort by last-modification time (oldest first). . is for regular-files only (equivalent of find's -type f), D is to include hidden (Dot) ones like find would by default.

If you get a arg list too long error, you can use zargs:

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

With bash (or any shell supporting Ksh-style process substitution) and recent GNU tools, an equivalent would be:

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