Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

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
share|improve this question
    
What is 2013007000385 supposed to represent? I guess 2013 is the year, but how do you get from 007000385 to Feb 7? –  Gilles Feb 12 '13 at 0:44
    
@Gilles: Supposed to be 20130207003851. Didn't copy it correctly or ... sorry for that. –  Radek Feb 12 '13 at 0:48

2 Answers 2

up vote 3 down vote accepted

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
share|improve this answer
    
only the find part find -newermt "$timestring" -printf '%M@\t%f %Mb %Md %MH:%MM\n' gives me funny output -rwxrwxrwx@ S0002975.LOG -rwxrwxrwxb -rwxrwxrwxd -rwxrwxrwxH:-rwxrwxrwxM –  Radek Feb 12 '13 at 1:25
    
@Radek Sorry, it's %T for the mtime, %M is the permissions. –  Gilles Feb 12 '13 at 1:29
    
Beautiful. Works smoothly. My final code is find /tmp -maxdepth 1 -type f -newermt "20130207 00:38:51" -printf '%T@\t%f-%Tb %Td %TH:%TM\n' | sort -k1n | cut -f 2- I separated file name and time by - because I will capture the output in php and use - as separator. Thank you so much. –  Radek Feb 12 '13 at 1:37
    
@Gilles it's awesome, but if you explain timestring , it will help more.. –  Rahul Patil Feb 12 '13 at 3:37
    
@RahulPatil Done. I also added a more readable bash method. –  Gilles Feb 12 '13 at 10:32

With zsh:

zmodload zsh/stat
newer() {
  local t
  zstat -A t -F %Y%m%d%H%M%S +mtime -- $REPLY && (( t >= timestamp ))
}
timestamp=20130207003851
print -rl -- /tmp/*(D.Om+newer)

The newer function returns true for files newer than $timestamp (note that zsh's zstat doesn't support subsecond accuracy though).

Then all we do is use zsh globbing qualifiers: D to include dot files, . to only consider regular files, Om to order on modification time, and +newer to call the newer function to determine which file to select.

If you want to display the file timestamps as well, you can change newer to:

newer() {
  local t
  zstat -A t -F %Y%m%d%H%M%S +mtime -- $REPLY &&
    REPLY+=$'\t'$t &&
    (( t >= timestamp ))
}

Note though that the result of the filename generation will include the timestamps which means you can't use those as filenames any more.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.