How do I find a the last created file in the current directory on a Linux machine?
Note: I don't know the mtime.
A solution which is safe for files with spaces within the filename. Strings are terminated with 0
with print0
.
$ touch "file with spaces"
$ find . -maxdepth 1 -type f -print0 | xargs -0r ls -ltr | tail -1
-rw-rw-r-- 1 jris jris 0 jun 3 15:35 ./file with spaces
or maybe simpler:
ls -ltrp | grep -v / | tail -1
-p
adds a trailing /
to directories and then grep
removes them.
xargs
? The other answers, piping ls
into head
or tail
, handle filenames with spaces, and your xargs
solution doesn’t handle filenames with newlines.
Jun 3, 2014 at 23:11
Linux doesn't store a timestamp for the birth of a file, but if no other files have been changed in the directory since its creation, you can sort the files by their modification time and return the first.
ls -at | head -1
-1
; ls
automatically goes into one file per line mode when the output is redirected. (2) You do need to say -a
, in case the file’s name begins with a period.
Jun 3, 2014 at 23:08
-a
might be ..
or .
which could be trouble for certain scripts.
ls -A
that show dot files at the exception of ..
and .
Jun 4, 2014 at 0:14
.
and ..
. (The again, since the question says “last created file”, the right answer might be ls -atl | grep "^-" | head -1
.)
Jun 4, 2014 at 13:43
If you are on an ext filesystem, you can use debugfs
to get the creation date of an inode. So, you could collect the inodes for each file in the current directory and then sort by creation time:
#!/usr/bin/env bash
## This will hold the newest timestamp
newestT=0
## Get the partition we are running on
fs=$(df --output=source "$@" | tail -1);
## Iterate through the files in the directory
## given as a target
for file in "$@"/*; do
## Only process files
if [ -f "$file" ]; then
## Get this file's inode
inode=$(ls -i "$file" | awk 'NR==1{print $1}');
## Get its creation time
crtime=$(sudo debugfs -R 'stat <'"${inode}"'>' $fs 2>/dev/null | grep -oP 'crtime.*-- \K.*');
## Convert it to a Unix timestamp
timestamp=$(date -d "$crtime" +%s)
## Is this newer than the newest?
if [[ $timestamp -gt $newestT ]]; then
newestT=$timestamp;
newest="$file";
fi
fi
done
## Print the newest file
echo "$newest"
Save the script above as ~/bin/get_newest.sh
, make it executable (chmod 744 get_newest.sh
) and run like this:
~/bin/get_newest.sh /target/directory
Unlike the other answers, this one will actually return the newest file in terms of its creation date, not the one that was modified most recently.
It will only work on ext4 (perhaps 3, not sure) filesystems.
It can deal with any file names, spaces and newlines etc are not a problem.
Classic Unix filesystems don't store file creation time. The closest you get on classic filesystems is inode creation time. This is not when the file is created in the current directory, but when it was created on that filesystem. If it moves, the inode is moved, but the creation time stays the same. If you "move" across filesystems, that's really a copy+rm and the inode is created on the new filesystem. This may or may not be what you want.
The command: ls -1c | head -1
will find the latest inode creation time.
ls –c
shows inode change time, which is similar to modification time but even worse (even more volatile). (And see my other comment about ls -1
.)
Jun 3, 2014 at 23:13