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:
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:
my @file_lists = `find path-name type -f -name "aliencoders\.*" | xargs -r ls -lRt | awk '{ print \$9 }'`;
#we need to extra of those special characters in Perl while using system commands.
#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 }'
Updates:
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