Best way to list 100 first files in a directory sorted by time
Solution 1:
You say that "ls piped to head takes an awful long time to complete".
The cause of this is not ls
, but the number of files in your directory. If you have 100,000 files in a single directory, any way of solving this problem would have to get information about all 100,000 files before it could even think about sorting them or printing any output.
If it's taking too long, the real solution is to split the files over multiple directories.
If you can't spread the files over several directories, is there any way you can narrow down the number of files to consider? e.g. if the file names include a date, maybe you can include a wildcard so the system doesn't have to sort 100,000 files. Or maybe they're sequentially numbered? (This may or may not help, but is worth trying.)
How many times are you trying to do this? Maybe it's worth saving/caching the output for re-use.
Now, a question.
Are you sure you mean "creation time" and not "change time"? Most tools can only display "change time", not "creation time".
Getting "creation time" is a very new thing, which requires an ext4 filesystem, and some tools that aren't easy to install.
If you want change time
Change time (ctime for short) means the time the attributes of the file last changed.
ls -c
sorts by ctime.
You want the output in ascending order, not descending, so you need to reverse the output with the -r
option too.
So you could do it like this:
ls -cr | head -n 100
A longer solution to the same problem using stat
:
find . -mindepth 1 -maxdepth 1 -exec stat -c $'%Z\t%n' '{}' \; |
sort -k 1n |
cut -f 2 -d $'\t' |
head -n 10 |
sed -e 's/^\.\///'
but that runs slower than ls -cr
on my system.
If you want modification time
Modification time (mtime for short) means the time the contents of the file last changed.
ls -t
sorts by mtime.
Change ls -cr
to ls -tr
(best option) or change stat -c $'%Z\t%n'
to stat -c $'%Y\t%n'
.
If you need creation time
(crtime for short)
This is harder.
First, ensure the directory is on a filesystem that is formatted using ext4
. You can use tune2fs -l <device name>
to check this.
Then, there is a new stat
format called %W
, which can help you here. To get it, you'll have to download a version of GNU Coreutils released in October 2010 or after, extract it, compile it, and install it.
Then, depending on your kernel, this might work (haven't tried it).
find . -mindepth 1 -maxdepth 1 -exec stat -c $'%W\t%n' '{}' \; |
sort -k 1n |
cut -f 2 -d $'\t' |
head -n 10 |
sed -e 's/^\.\///'
See also:
- stat read crtime from ext4
- a Ruby script to access crtime on Linux
If you get errors about "'$\t'
The '$\t'
notation requires bash
or zsh
: it will not work in dash
or sh
on Ubuntu. If you really need to use those shells, you will need to change any \t
to Ctrl+V, Tab and remove the leading $
from just before the opening quote.
Solution 2:
Another way if found of doing things today might be relevant to your performance issues:
I=0; ls -cr /dir/ | while read file; do I=`expr $I + 1`; echo "$file"; if [ $I == 100 ]; then break; fi; done
That should in theory start outputting a lot faster but I guess it depends where the lag is coming from. It could just be taking ls
a long time to sort the files.