Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get most recent file in a directory on Linux

People also ask

How do I find the latest file created in Linux?

Finding Files Modified on a Specific Date in Linux: You can use the ls command to list files including their modification date by adding the -lt flag as shown in the example below. The flag -l is used to format the output as a log. The flag -t is used to list last modified files, newer first.

How do I find new files?

File Explorer has a convenient way to search recently modified files built right into the “Search” tab on the Ribbon. Switch to the “Search” tab, click the “Date Modified” button, and then select a range. If you don't see the “Search” tab, click once in the search box and it should appear.

How do I get the latest file folder from the last run?

How to get latest files from folder based on last run. The simplest (the better?) is to move (using tfilecopy) the files to a special folder (archive for example) as soon they have been processed. Using this pattern, you don't have to worry about how many files you have processed last day.


ls -Art | tail -n 1

Not very elegant, but it works.

Used flags:

-A list all files except . and ..

-r reverse order while sorting

-t sort by time, newest first


ls -t | head -n1

This command actually gives the latest modified file in the current working directory.


This is a recursive version (i.e. it finds the most recently updated file in a certain directory or any of its subdirectory)

find /dir/path -type f -printf "%T@ %p\n" | sort -n | cut -d' ' -f 2- | tail -n 1

Brief layman explanation of command line:

  • find /dir/path -type f finds all the files in the directory
    • -printf "%T@ %p\n" prints a line for each file where %T@ is the float seconds since 1970 epoch and %p is the filename path and \n is the new line character
    • for more info see man find
  • | is a shell pipe (see man bash section on Pipelines)
  • sort -n means to sort on the first column and to treat the token as numerical instead of lexicographic (see man sort)
  • cut -d' ' -f 2- means to split each line using the character and then to print all tokens starting at the second token (see man cut)
    • NOTE: -f 2 would print only the second token
  • tail -n 1 means to print the last line (see man tail)

A note about reliability:

Since the newline character is as valid as any in a file name, any solution that relies on lines like the head/tail based ones are flawed.

With GNU ls, another option is to use the --quoting-style=shell-always option and a bash array:

eval "files=($(ls -t --quoting-style=shell-always))"
((${#files[@]} > 0)) && printf '%s\n' "${files[0]}"

(add the -A option to ls if you also want to consider hidden files).

If you want to limit to regular files (disregard directories, fifos, devices, symlinks, sockets...), you'd need to resort to GNU find.

With bash 4.4 or newer (for readarray -d) and GNU coreutils 8.25 or newer (for cut -z):

readarray -t -d '' files < <(
  LC_ALL=C find . -maxdepth 1 -type f ! -name '.*' -printf '%T@/%f\0' |
  sort -rzn | cut -zd/ -f2)

((${#files[@]} > 0)) && printf '%s\n' "${files[0]}"

Or recursively:

readarray -t -d '' files < <(
  LC_ALL=C find . -name . -o -name '.*' -prune -o -type f -printf '%T@%p\0' |
  sort -rzn | cut -zd/ -f2-)

Best here would be to use zsh and its glob qualifiers instead of bash to avoid all this hassle:

Newest regular file in the current directory:

printf '%s\n' *(.om[1])

Including hidden ones:

printf '%s\n' *(D.om[1])

Second newest:

printf '%s\n' *(.om[2])

Check file age after symlink resolution:

printf '%s\n' *(-.om[1])

Recursively:

printf '%s\n' **/*(.om[1])

Also, with the completion system (compinit and co) enabled, Ctrl+Xm becomes a completer that expands to the newest file.

So:

vi Ctrl+Xm

Would make you edit the newest file (you also get a chance to see which it before you press Return).

vi Alt+2Ctrl+Xm

For the second-newest file.

vi *.cCtrl+Xm

for the newest c file.

vi *(.)Ctrl+Xm

for the newest regular file (not directory, nor fifo/device...), and so on.


I use:

ls -ABrt1 --group-directories-first | tail -n1

It gives me just the file name, excluding folders.


ls -lAtr | tail -1

The other solutions do not include files that start with '.'.

This command will also include '.' and '..', which may or may not be what you want:

ls -latr | tail -1