How do I get the latest file from a list of files in a particular directory?

119,192

Solution 1

ls -t1 |  head -n 1

The first will list all files ordered by access time, the latter select the first line.

Solution 2

In zsh, the latest file in the current directory is

a=(*(om[1]))
latest_file=$a[1]
cp -p $latest_file /other/directory

(Glob qualifiers rock, but unfortunately the result is still a list even if you only request one element, hence the temporary array a.)

In other shells, if you know that your file names cannot contain newlines or unprintable characters, you can use ls:

latest_file=$(ls -t | head -n 1)
cp -p "$latest_file" /other/directory

However, it seems that what you're really asking for is the list of files that are newer than a particular file. For this, you can use the -cnewer builtin of find to detect files whose content or metadata has changed more recently than some other files. Note that the way I invoke it here, find also collects files in subdirectories.

find . -cnewer "$previous_latest_files" -exec sh -c 'cp -p "$@" "$0"' /other/directory {} +

The problem remains to detect the previous latest file… In fact, what matters is the date of the copy. So create a marker file when you do the copy.

find . -cnewer marker_file -exec sh -c 'cp -p "$@" "$0"' /other/directory {} +
touch marker_file

If the files remain in the target directory, then you can simply synchronize the two directories. Note that if you delete some old files from the target directory but they remain in the source directory, they'll be copied again with this method.

rsync -a . /other/directory/

Solution 3

If you're just copying files from one directory to another based on their modification times, you might consider rsync. A very simple way to do the same might be:

rsync -t ./dir1/ ./dir2/

Or just to see what it would do add:

rsync -t --list-only ./dir1/ ./dir2/

As Gilles notes in a comment below there may be extenuating circumstances that obviate the use of the -t option for you. But if you take anything away from this let it be that you can and should test for the results you desire and that rsync's --list-only option is a very simple means of doing so.

Also, maybe...

man rsync

Solution 4

If your actual objective is to move a bunch of files based on modification time and your system's version of find supports the -newerXY type of tests, you could do something like

find -type f -newermt "@$lasttime" -exec mv -t path/to/destination/ {} +

where $lasttime is the file modification time that you saved previously, in seconds since epoch (e.g. as obtained from stat -c %Y yourfile).

You could also use find -newer somefile or find -newermm somefile to compare the modification times to that of a reference file directly, instead of saving the reference file's timestamp in a variable.

To limit the selection to the current directory (exclude subdirectories) you can add -maxdepth 1 to the find command.

Share:
119,192

Related videos on Youtube

peterh
Author by

peterh

Truthful words are not beautiful; beautiful words are not truthful. (Lao Tze) The Last Question

Updated on September 18, 2022

Comments

  • peterh
    peterh almost 2 years

    I need to get the latest file from a list of files in a particular directory.

    When I run the script the first time I've copied the list of files in a particular directory to another directory.

    From the second run I need to get the latest files from a list of files in same directory to copy those files into the other directory.

    Here in the first run I'm capturing the last file's creation date into a variable, when the script runs a second time, files that are greater than the last file creation date in the first run; these files need to be copied to the other directory.

    Please could anyone help me out to get the latest files?

  • Gilles 'SO- stop being evil'
    Gilles 'SO- stop being evil' about 10 years
    Caveat: if files are deleted from dir2 but not dir1, they'll be copied again. The question doesn't have enough information to know whether it's an issue.
  • mikeserv
    mikeserv about 10 years
    @Gilles: True. tar might be leveraged in that case. rsync itself also offers as many additional sync points as you could wish for. Still, there's certainly not enough data in the question to know that it is. I too often solve problems that aren't there - if I'm not causing them - but this time I didn't.