- How to recursively find and list the latest modified files in a directory with subdirectories and times
- 22 Answers 22
- Ignoring hidden files — with nice & fast time stamp
- How to Find Last Modified Files in Linux?
- Finding last day modified files in Linux:
- Find Last Modified Specific File Type in Linux:
- Finding Last Hour Modified Files in Linux:
- Finding Files Modified on a Specific Date in Linux:
- Find Last Modified Files Recursively:
- Search File by Date Omitting Files or Directories:
- Find Files by Access Date:
- Conclusion:
- About the author
- David Adams
How to recursively find and list the latest modified files in a directory with subdirectories and times
I have several directories with several subdirectories and files in them. I need to make a list of all these directories that is constructed in a way such that every first-level directory is listed next to the date and time of the latest created/modified file within it.
To clarify, if I touch a file or modify its contents a few subdirectory levels down, that timestamp should be displayed next to the first-level directory name. Say I have a directory structured like this:
and I modify the contents of the file example.txt , I need that time displayed next to the first-level directory alfa in human readable form, not epoch. I’ve tried some things using find, xargs , sort and the like, but I can’t get around the problem that the filesystem timestamp of ‘alfa’ doesn’t change when I create/modify files a few levels down.
@user3392225 A fork of github / shadkam / recentmost can be found at github.com/ConradHughes/recentmost with the -0 option to use with find ‘s -print0
22 Answers 22
#!/bin/bash find $1 -type f -exec stat --format '%Y :%y %n' "<>" \; | sort -nr | cut -d: -f2- | head
Execute it with the path to the directory where it should start scanning recursively (it supports filenames with spaces).
If there are lots of files it may take a while before it returns anything. Performance can be improved if we use xargs instead:
#!/bin/bash find $1 -type f -print0 | xargs -0 stat --format '%Y :%y %n' | sort -nr | cut -d: -f2- | head
Your «fast method» should also be able to use print0 to support spaces and even linefeeds in filenames. Here’s what I use: find $1 -type f -print0 | xargs -0 stat —format ‘%Y :%y %n’ | sort -nr | cut -d: -f2- | head This still manages to be fast for me.
Some directories I was looking in didn’t allow me to stat them, so I made the following changes (to the ‘fast’ one) so I didn’t have to see the errors in my final output. find $ <1>-type f | xargs stat —format ‘%Y :%y %n’ 2>/dev/null | sort -nr | cut -d: -f2-1>
On Mac OS X it’s not GNU’s stat so command fails. You have to brew install coreutils and use gstat instead of stat
You don’t need to run stat since find PATH -type f -printf «%T@ %p\n»| sort -nr does the job. It’s also a bit faster that way.
On Mac OS X, without installing gstat or anything else, you can do: find PATH -type f -exec stat -f «%m %N» «<>» \; | sort -nr | head
To find all files whose file status was last changed N minutes ago:
Use -ctime instead of -cmin for days:
On FreeBSD and MacOS: You can also use -ctime n[smhdw] for seconds, minutes, hours, days, and weeks. Days is the default if no unit is provided.
# FreeBSD and MacOS only: find . -ctime -30s find . -ctime -15 find . -ctime -52w
great idea. Consider doing stat . on directory first to get an idea of modification dates you should be looking at
GNU find (see man find ) has a -printf parameter for displaying the files in Epoch mtime and relative path name.
redhat> find . -type f -printf '%T@ %P\n' | sort -n | awk ''
Thanks! This is the only answer that is fast enough to search through my very wide directory structure in a reasonable time. I pass the output through tail to prevent thousands of lines from being printed in the output.
Another comment: the awk ‘
The -printf variant is far quicker than calling a ‘stat’ process each time — it cut hours off my backup job(s). Thanks for making me aware of this. I avoided the awk/sed thing as I’m only concerned about the last update within the tree — so X=$(find /path -type f -printf ‘%T %p\n’ | grep -v something-I-don-tcare-about | sort -nr | head -n 1) and a echo $ worked well for me (give me stuff up to the first space)
All will not works if filename across multiple line. Use touch «lala
stat --printf="%y %n\n" $(ls -tr $(find * -type f))
If there are spaces in filenames, you can use this modification:
OFS="$IFS";IFS=$'\n';stat --printf="%y %n\n" $(ls -tr $(find . -type f));IFS="$OFS";
This will not work if you have a very large number of files. the answers that use xargs solve that limit.
@carlverbiest indeed a large number of files will break slashdottir’s solution. Even xargs-based solutions will be slow then. user2570243’s solution is best for big filesystems.
IFS=$’\n’ isn’t safe in any event when handling filenames: Newlines are valid characters in filenames on UNIX. Only the NUL character is guaranteed not to be present in a path.
#!/bin/bash stat --format %y $(ls -t $(find alfa/ -type f) | head -n 1)
It uses find to gather all files from the directory, ls to list them sorted by modification date, head for selecting the first file and finally stat to show the time in a nice format.
At this time it is not safe for files with whitespace or other special characters in their names. Write a commend if it doesn’t meet your needs yet.
halo: I like your answer, it works well and prints out the correct file. I doesn’t help me however since there are too many sublevels in my case. So I get «Argument list too long» for ls. and xargs wouldn’t help in this case either. I’ll try something else.
I solved this using PHP instead. A recursive function that descends through the filesystem tree and stores the time of the most recently modified file.
On MacOS I needed to use stat $(ls -t $(find alfa/ -type f) | head -n 10) . —format would be -f , but there is no %y and I didn’t bother finding a replacement.
Ignoring hidden files — with nice & fast time stamp
Here is how to find and list the latest modified files in a directory with subdirectories. Hidden files are ignored on purpose. Whereas spaces in filenames are handled well — not that you should use those! The time format can be customised.
$ find . -type f -not -path '*/\.*' -printf '%TY.%Tm.%Td %THh%TM %Ta %p\n' |sort -nr |head -n 10 2017.01.25 18h23 Wed ./indenting/Shifting blocks visually.mht 2016.12.11 12h33 Sun ./tabs/Converting tabs to spaces.mht 2016.12.02 01h46 Fri ./advocacy/2016.Vim or Emacs - Which text editor do you prefer?.mht 2016.11.09 17h05 Wed ./Word count - Vim Tips Wiki.mht
More find galore can be found by following the link.
This command works on Mac OS X:
find «$1» -type f -print0 | xargs -0 gstat —format ‘%Y :%y %n’ | sort -nr | cut -d: -f2- | head
On Linux, as the original poster asked, use stat instead of gstat .
This answer is, of course, user37078’s outstanding solution, promoted from comment to full answer. I mixed in CharlesB’s insight to use gstat on Mac OS X. I got coreutils from MacPorts rather than Homebrew, by the way.
And here’s how I packaged this into a simple command ~/bin/ls-recent.sh for reuse:
#!/bin/bash # ls-recent: list files in a directory tree, most recently modified first # # Usage: ls-recent path [-10 | more] # # Where "path" is a path to target directory, "-10" is any argument to pass # to "head" to limit the number of entries, and "more" is a special argument # in place of "-10" which calls the pager "more" instead of "head". if [ "more" = "$2" ]; then H=more; N='' else H=head; N=$2 fi find "$1" -type f -print0 |xargs -0 gstat --format '%Y :%y %n' \ |sort -nr |cut -d: -f2- |$H $N
How to Find Last Modified Files in Linux?
This tutorial explains how to find last modified files in Linux using different commands and according to custom needs.
After reading this tutorial you’ll know how to execute the following tasks:
- How to find files modified in a specific day range
- How to find last modified specific file type (e.g mp4, png)
- Finding files modified before / after X minutes
- How to find files modified in a specific date
- Finding modified files recursively
- Search omitting files or directories
- Find files by access date
Finding last day modified files in Linux:
To start, let’s search files modified less than a day ago. To find files modified a day ago you can use the commands find and newermt used in the following example.
The find command is used to search files. The newermt command compares files timestamp with the argument passed, in this case “1 day ago”. Then, the ls command is passed to list the files.
To find last day modified files, you can also use the mtime command together with find. By specifying the option 0 as in the example below, mtime will return all files modified in the last 24 hours.
Find Last Modified Specific File Type in Linux:
You can use a wildcard to limit your search to a specific file type. In the following example, find and newermt are instructed to list all mp4 files modified a day ago.
cc lang=”bash” width=”100%” height=”100%” escaped=”true” theme=”blackboard”]$ find /home/linuxhint/*.mp4 -newermt “1 day ago” -ls[/cc
In the following example, find and newermt are used to find all .png images less than 15 days old.
Finding Last Hour Modified Files in Linux:
The following example combines the find command with the mmin command. We can use the mmin command to specify minutes. In the example below, the find and mmin commands will print all files under the /root directory, whose modifications are less than 60 minutes old.
Contrary to the previous example in which files modified in the past 60 minutes were found. You can also use +mmin to search files modified after X minutes. For example, the following command will show files modified 60 minutes ago or more.
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.
Then you can combine ls -lt with grep to print all files which were modified on a specific date.
Find Last Modified Files Recursively:
Previous examples are useful to find last modified files
The command below can be used to print last modified files recursively.
Search File by Date Omitting Files or Directories:
Contrary to the previous example, you can search files omitting directories. For this purpose, you need to implement the -type flag with the option f (file) as shown in the following example. As a result, you’ll see only final files and no directories.
You can also search directories only and the output will omit files. For this, just replace the f with a d after the -type flag.
Find Files by Access Date:
You also may want to find unmodified files by access date. For this purpose, you can use the atime command. It is similar to the mtime command explained before, but instead of identifying files by modification, it can display files by access. With this command you can learn the last accessed files and directories in the system.
The following command shows all files accessed in the past 10 days.
Like the previous command, you can also use the d option to show only directories:
If you don’t specify a type, atime will show all files and directories:
In the following example, find and atime are used to find files and directories with modification older than 20 days.
As with previous examples, you can also limit the listing to files or directories with the -type flag.
Conclusion:
As you can see, Linux offers different methods to find files according to modification time. Any Linux user level can easily learn those methods to search files with a single command. Finding files by modification or access within a system is part of the basic knowledge a Linux user needs.
I hope this tutorial was useful. Keep following Linux Hint for more Linux tips and tutorials.
About the author
David Adams
David Adams is a System Admin and writer that is focused on open source technologies, security software, and computer systems.