Shell – list all files newer than given timestamp and sort them

findlsshell-scripttimestamps

I want to list all files (sorted by date) that are newer than timestamp in format 20130207003851 in directory /tmp only. Subdirectories can be omitted.

Using SUSE Linux Enterprise Server 11.

The output format should be

S0002948.LOG Feb  7 03:28 
S0002935.LOG Feb  7 05:58 
S0002952.LOG Feb  7 09:58 
S0002940.LOG Feb  7 11:58 

find /tmp -newermt "7 feb 2013" -ls lists the files I want but

  • how can I use the timestamp in a format 20130207003851
  • how can I sort the output?
  • how can I display only file name and date. File name first and then the date?

ps I don't want to use touch to create reference file for find

pss

find -newermt "20130207003851" -ls
find: I cannot figure out how to interpret `20130207003851' as a date or time

Best Answer

find supports a lot of date input formats. The simplest format to obtain is YYYYMMDD HH:MM:SS. You already have the digits in the right order, all you have to do is extract the first group (${timestamp%??????}: take all but the last 6 characters; ${timestamp#????????}: take all but the first 8 characters), and keep going, appending punctuation then the next group as you go along.

timestamp=20130207003851
timestring=${timestamp%??????}; timestamp=${timestamp#????????}
timestring="$timestring ${timestamp%????}"; timestamp=${timestamp#??}
timestring="$timestring:${timestamp%??}:${timestamp#??}"

In bash (and ksh and zsh), but not in ash, you can use the more readable ${STRING_VARIABLE:OFFSET:LENGTH} construct.

timestring="${timestamp:0:8} ${timestamp:8:2}:${timestamp:10:2}:${timestamp:12:2}"

To sort files by date, print out the file names preceded by the dates and sort that, then strip the date prefix. Use -printf to control the output format. %TX prints a part of the modification time determined by X; if X is @, you get the number of seconds since the Unix epoch. Below I print three tab-separated columns: the time in sortable format, the file name, and the time in human-readable format; cut -f 2- removes the first column and the call to expand replaces the tab by enough spaces to accommodate all expected file names (adjust 40 as desired). This code assumes you have no newlines or tabs in file names.

find -maxdepth 1 -type f \
     -newermt "$timestring" -printf '%T@\t%f\t%Tb %Td %TH:%TM\n' |
sort -k1n |
cut -f 2- |
expand -t 40
Related Question