Skip to main content

Finding files sorted with time in a given directory

No replies
sanjeev's picture
Joined: 21 Feb 2011

I had one scenario where:

  • I needed to select all files having aliencoders. and then anything after that  like aliencoders.* (with dot has its real meaning like aliencoders.1906 or aliencoders.jun-19-2012 ).
  • It should look into all sub directories too
  • It should sort it by time in descending order i.e. recent file at the top
  • It should print all such file name in that order

I got it using find command with xargs after having lots of issues before getting final code snippet:

  1. find /home/jassi/ -name "aliencoders.[0-9]+" | xargs ls -lrt | awk print '$9'

Final solution is:
On Linux box

find  path-name type -f -name "aliencoders.*" | xargs -r ls -lRt | awk '{ print $9 }'

In Perl code:

  2. my @file_lists = `find path-name type -f -name "aliencoders\.*" | xargs -r ls -lRt | awk '{ print \$9 }'`;
  3. #we need to extra of those special characters in Perl while using system commands.
  4. #Like we had to escape . with \. and $ to \$ so that it should read as it is like Linux shell.

Problems I faced before coming to final solution:

Problem 1:
When I tried to find aliencoders.* using find command i.e. find path-name -name "aliencoders.*"
and it worked fine till it finds even a single file by that name. But problem was it was printing the parent directory name also as it was also having aliencoders.* structure
So I have to pass one more argument -type f which will check if filter output is a file type or not.
So now find command became :  find  path-name type -f -name "aliencoders.*"

Problem 2:
Once we pipe the output of find command to xargs , i.e. xargs ls - lRt ( to list all files in descending order by time)
Then one more problem came into the picture.
If it gets the output from previous command i.e. find then it was working and if no output from find command then it was listing whole files with all sub directories lists. So to avoid it we had to use one more arguments in xargs command which will not invoke it if there is no input from previous command. So, we used -r option for it. i.e xargs -r ls -lRt

Like: find  path-name type -f -name "aliencoders.*" | xargs -r ls -lRt

Problem 3:
Now i was getting everything that we were supposed to get except the final output which was printing everything from ls command but i actually needed the last column of ls command which was the file name. ls -lRt command will give 9 columns as output. So printing the last column using awk would be the nicer way to accomplish our task.
So, I used awk '{print $9}'   #$9 means the 9th column. if we needed to know the month also we might have used $6 and so on

So the final solution for this problem was:
find  path-name type -f -name "aliencoders.*" | xargs -r ls -lRt | awk '{ print \$9 }'

If by any chance, you have to work with regex on your files don't use name ,instead you should use regex option.
Say I wanted only aliencoders.digits then I had to write
my @cores = `find $cgi_dir -type f -regex \".*/core\.[0-9]*\" | xargs -r ls -lRt | awk \'{print \$9}\'`; #in Perl

Because with -name option regular expression will not work the way you though. It will take *, + $ the way it should take.
With -name option  you don't specify a regular expression but a glob pattern.

So to use regular expression at full fledge use regex option in find command.

I hope it will solve someone's issue too

Follow us at :
Facebook | Twitter
########### Give me the right place to stand, I shall move the earth. #################

Post new comment

The content of this field is kept private and will not be shown publicly.
This question is for testing whether you are a human visitor and to prevent automated spam submissions.
Enter the characters shown in the image.