To get the files in a directory for the given date (User entered date)

Need a ksh script to get the files that were created or modified in a directory on a particular date entered by the user.

For example if a directory contains files as below :

> ll
total 41
-rw-rw-r--    1 psn      psn           199 Aug 23 07:06 psn_roll.sh
-rw-rw-r--    1 psn      psn           451 Aug 24 09:24 x.log
-rw-rw-r--    1 psn      psn           451 Aug 23 05:27 y.log
-rwxrwxr-x    1 psn      psn           451 Aug 24 09:29 z.log
-rw-rw-r--    1 psn      psn           233 Aug 23 09:28 Items1.txt
-rw-rw-r--    1 psn      psn           233 Aug 24 12:00 Items2.txt
drwxrwxr-x    2 psn      psn          2119 Aug 23 08:44 final
-rwxrwxr-x    1 psn      psn             6 Aug 25 08:36 sample.sh
-rw-rw-r--    1 psn      psn            85 Aug 23 06:17 best.log

When a user enters a date 2013/08/23

I have to get the files that were created or modified on that date.

Desired output:

Enther the date: 2013/08/23

psn_roll.sh
y.log
Items1.txt
best.log

Date manipulation is very system specific what Operating system is this to be run on (e.g. output from uname -a )?

Not accessible to machine now. But I use AIX 6.1 OS machine with ksh88 version.

Hope this will be helpful.

Unfortunately your options for date manulipitation under AIX 6.3 are limited.

I'd suggest using perl to convert entered date to epoch time and work with that.

#!/bin/ksh

printf "Enter date: "
read date

year=${date%%/*}
month=${date#*/}
month=${month#0}
month=${month%%/*}
let month=month-1
day=${date##*/}

epoch=`perl -e "use Time::Local; print timelocal(0,0,0,$day,$month,$year);"`
now=`date +%s`
let age=now-epoch
let age=age/86400

find . -mtime $age -print

---------- Post updated at 08:18 AM ---------- Previous update was at 07:38 AM ----------

Some testing of this solution reveals that find will use the current time when matching so files listed will not always be on correct date (uses 24 hours before current time on the target date)

Also the output of ls changes when files are older than 1 year so greping directly form ls is not reliable.

Best bet is to grep the output of the AIX istatus command that lists files actual timestamps something like this should work for you (I don't have AIX available to test it fully).

#!/bin/ksh

printf "Enter date: "
read date

year=${date%%/*}
month=${date#*/}
month=${month#0}
month=${month%%/*}
let month=month-1
day=${date##*/}

TIMEMATCH=`perl -e 'use Time::Local; 
use POSIX qw(strftime);
print strftime("%a %b %e .* %Y", localtime(timelocal(0,0,0,'"$day,$month,$year)));"`

for file in *
do
   istatus "$file" | grep -q "$TIMEMATCH" && echo $file
done
1 Like

Thanks for your solution.

Unfortunately I dont have the required perl modules installed in my machine neither I do not have admin rights for that machine to install the required modules.

Kindly help me with some other solution.

Do you have a C compiler available in your environment?

This script I wrote may help you. I tested it on one of our AIX boxes and it seems to work pretty well. Might require some tweaking but should get you going down the right path.

#!/bin/bash
#
# showFiles.sh
#
# -- script to list files based on given date
#

# check command-line for argument
if [ $# -ne 1 ]
then
    echo "Usage: ${0##*/} <date in format YYYY/MM/DD>"
    exit 1
fi

# store the given date
dt=$1

# setup our hash table of months
#declare -a months
months=(
    key01='Jan'
    key02='Feb'
    key03='Mar'
    key04='Apr'
    key05='May'
    key06='Jun'
    key07='Jul'
    key08='Aug'
    key09='Sep'
    key10='Oct'
    key11='Nov'
    key12='Dec'
)

# function to retrieve the matching month
# given the numerical version
function getMonth()
{
    local _hashtable="$1";
    local _hashkey="$2";
    local _hashvalue="${_hashtable}[@]";
    local "${!_hashvalue}";
    eval echo "\$${_hashkey}";
}

# let's split up the given date into variables
read yy mo dy <<<$(echo $dt | sed 's/\// /g')

# access our hash table and retrieve the correct
# month name and create our date string
date_string=$(echo $(getMonth months $(echo "key${mo}")) $dy $yy)

# get the current directory and switch to it
cdir=$(echo $PWD)
cd $cdir

# run the ls command and grep for files with our date
# string
ls -l | tr -s ' ' | grep "$date_string" | awk '{print $9}'

# done
exit 0

./showFiles.sh 2013/08/23

Also, with files that are within that 6 month modication window that do not show the year, entering the date string like so seems to work (just omitting the year):

./showFiles.sh /08/23

Good luck.

39798d2bb39bd147cd2e7bec2fd0b130

Unfortunately no.

In between I came across this piece of code in Google which seems to working fine in bash but not in ksh (ksh88)

find . -type f -mtime $(( ( $(date +%s) - $(date -d '2013-10-08' +%s) ) / 60 / 60 / 24 - 1 ))

In ksh m getting an error like the

flag -d is not recognized 

So is there any flag in ksh to serve this purpose.

Another thought is to use touch to create a file in /tmp with the date stamp and the ls -l the temp file to fetch the ls string required

Of course the column positions (44-50) will need adjusting for your ls output under AIX

#!/bin/ksh

printf "Enter date: "
read date

year=${date%%/*}
year=${year#..}
month=${date#*/}
month=${month%%/*}
day=${date##*/}

TIMEMATCH=`touch -t ${year}${month}${day}0000 /tmp/df_$$ ; ls -l /tmp/df_$$ | cut -c44-50 ; rm /tmp/df_$$`

echo "DEBUG: Timematch is \"$TIMEMATCH\""

for file in *
do
   ls -l "$file" | grep -q "$TIMEMATCH" && echo $file
done

---------- Post updated at 05:58 AM ---------- Previous update was at 05:55 AM ----------

This the AIX date command - it doesn't support the -d option, this is why I said AIX is tricky.

I also pointed out earlier that the find mtime option will not work correctly, files created the day before the target date but later in the day than the runtime will be listed incorrectly. e.g. if you run your script at 10am for target date 2013/08/23 a file created on 2013/08/22 @ 3pm will also be found.

Thanks...!!! This was what I was looking for... But one problem here seems to be that it lists directory as well. I need only the filenames so I added an additional grep command with the code provided by you as given below

 
#!/bin/ksh
printf "Enter date: "
read date
year=${date%%/*}
year=${year#..}
month=${date#*/}
month=${month%%/*}
day=${date##*/}
TIMEMATCH=`touch -t ${year}${month}${day}0000 /tmp/df_$$ ; ls -l /tmp/df_$$ | cut -c
46-51; rm /tmp/df_$$ `
echo "DEBUG: Timematch is \"$TIMEMATCH\""
for file in *
do
ls -l "$file" | grep -q "$TIMEMATCH" | grep -q "^-" && echo $file
done

But this seems to be not working.

Remove -q form first grep in pipe (-q causes no output and sets the return status so should only be used on last grep in chain):

ls -l "$file" | grep -q "$TIMEMATCH" | grep -q "^-" && echo $file
1 Like