1. Introduction
Listing and sorting files is a very common task. Understanding how to arrange files in a specific order provides clarity and organization to our file system. For example, sorting files according to creation dates can be helpful in various scenarios like chronological organization, historical analysis, and identification of stale or redundant files.
In this tutorial, we’ll learn different ways to sort files according to their creation dates in Bash. In particular, we’ll sort the files according to their creation dates using the ls, stat, and find commands.
The code in this tutorial underwent testing on a Debian 12 (Bookworm) system using GNU Bash 5.1.16.
2. Environment Setup
First, let’s make sure that we have all the prerequisites ready, including files with different creation dates:
$ mkdir newdir && touch newdir/file1.txt
The mkdir command creates the newdir directory, while the touch command creates an empty file within that directory.
In addition to the newly created file, we also make a few more files with different creation dates. The use of hard links enables us to have files with shared timestamps, including the creation dates. In contrast, a new file has the current time as its default timestamp value for the creation date.
Instead of making new files, we’ll hard link to already existing files, thereby preserving their creation dates:
$ cp -l oldfile.txt newdir/newfile1.txt
This command creates a hard link named newfile1.txt in the directory newdir that points to the same data blocks as the file oldfile.txt. The newfile1.txt within the newdir directory is a hard link for an already existing file, i.e., oldfile.txt. Both of these files have the same creation dates as oldfile.txt.
The cp -l construct hard links files instead of copying. Thus, any changes made in the source files are reflected in the target files as they share the same data blocks due to the hard link.
Similarly, we can hard link a few more files:
$ cp -l olderfile.csv newdir/newfile2.csv
$ cp -l oldestfile.txt newdir/newfile3.txt
In addition, let’s create one more empty file within the newdir directory with the touch command:
$ touch newdir/file4.csv
Throughout the article, we use the files within the newdir directory to learn about sorting according to creation dates. Among all these files, newfile3.txt is the oldest, while file4.txt is the newest, i.e., the relative age matches the file numbers.
3. Using the ls Command
The ls command provides several options for listing information about the files.
We can use the –time option of ls to sort the files based on their modification, access, status change, or creation time:
$ ls -lt --time=birth newdir/
total 12
-rw-r--r-- 1 user baeldung 0 Feb 25 13:37 file4.txt
-rw-r--r-- 1 user baeldung 0 Feb 25 13:35 file1.txt
-rw-r--r-- 2 user baeldung 166 Feb 7 15:12 newfile1.txt
-rw-r--r-- 2 user baeldung 617 Jun 15 2023 newfile2.csv
-rw-r--r-- 2 user baeldung 401 Apr 20 2023 newfile3.txt
This command lists the contents of the newdir directory in a long listing format, sorted by file creation time in descending order.
Let’s understand each option:
- ls lists the contents of a directory, in this case newdir/
- -l sets the long listing format
- -t sorts the contents by time, the newest first
- –time=birth specifies the time attribute to be used for sorting, in this case, the file birth or creation time
We can also change the sorting order using the –reverse (-r) option:
$ ls -lt --time=birth --reverse newdir/
This command sorts the contents of newdir directory according to their creation dates, with the oldest files appearing first.
Although we can list using the –recursive (-R) option, the files within each subdirectory are listed according to their creation dates.
4. Using the stat Command
The stat command displays information about a file or file system.
In particular, the stat command provides information like file size, links, device, access permissions, access, modification, and creation times:
$ stat --format="%w %n" newdir/*
The above command prints the creation time of the files in human-readable format along with file names. Specifically, newdir/* indicates the path to the target files.
Notably, the –format option specifies the format in which the output should be displayed, in this case:
- %w represents the time of file birth in human-readable format
- %n is the file name
This way, we can use the sort command to sort the output of the above stat command:
$ stat --format="%w %n" newdir/* | sort -nr
2024-02-25 13:37:25.827156487 +0530 newdir/file4.txt
2024-02-25 13:35:13.218724591 +0530 newdir/file1.txt
2024-02-07 15:12:56.606987297 +0530 newdir/newfile1.txt
2023-06-15 03:24:24.807241794 +0530 newdir/newfile2.csv
2023-04-20 08:46:30.725585419 +0530 newdir/newfile3.txt
This pipeline displays the files within the newdir/ directory and sorts them according to their creation dates.
Let’s understand the new parameters we leveraged:
- | (pipe) takes the output of the stat command and passes it as input to the sort command
- sort arranges the lines according to its options and defaults
- -n performs a numerical sort based on the file creation times provided by the stat command
- -r (–reverse) reverses the sorting order of the results for comparison
We can also use %W instead of %w in the above command to display the time of file creation in seconds since Epoch. The Epoch is a reference time commonly set to January 1, 1970, at 00:00:00 UTC.
5. Using the find Command
The find command provides several options to search for files and directories.
We can use the -exec option of find coupled with the stat command to sort the files according to their creation dates:
$ find newdir/ -type f -exec stat --format="%w %n" {} + | sort -n
This way, we list the files in the newdir/ directory and below, sorted by creation dates, with the oldest files appearing first.
Let’s understand all the options:
- find newdir/ locates files within and under the newdir directory that have specific properties specified by the following parameters
- -type f restricts the search to regular files only
- -exec enables the execution of a command for each found file
- stat –format=”%w %n” invokes the stat command with the –format option display the creation dates and file names
- {} sets the placeholder for the input from stat
- + indicates the termination of the stat command and its options
- sort -n arranges the output lines numerically according to the numeric birth times
By default, the find command searches for files recursively. However, we can control and limit the depth of the search using the -maxdepth option.
Similarly, we can use the ls command along with the find -exec command option:
$ find newdir/ -maxdepth 1 -type f -exec ls -ltr --time=birth {} +
Although this command is similar to the one above in terms of sorting files based on their creation dates, the output format differs.
The find command provides a convenient way to search files recursively and sort them according to their creation dates. Furthermore, we can apply any additional filters like files with specific extensions, and then use the -exec option to sort these filtered files according to their creation dates.
6. Conclusion
In this article, we learned how to sort files according to creation dates in Bash.
First, we discussed the usage of ls for sorting the files and how to reverse the sorting order. Then, we leveraged the stat command with the –format option and sorted the output numerically with sort. Lastly, we used the find -exec command with the stat or ls commands which are best suited for recursive listing and sorting.
Although we can select any method depending on our preferences and needs, ls is the simplest way to sort files within a single flat directory according to their creation dates.