Program to search for the files with specific format

Hi All,

Your help on the below requirement is highly appreciated.
I am building a program which should pick the file from a source directory and place them into target directory. While selecting the file in source it should look for some pattern in the file name.

Ex:
File Name 1: ABC_I_05032017140330
File Name 2: ABC_I_07032017140340
File Name 3: ABC_I_07032017140312

All the above files are stored under same directory. My search should be like File name which starts with 'ABC' and File name contains '_I_' and the last part of the file is time stamp, My program have parameter to select the date range. so the search criteria should be like within that range, ex : Files which created between 07032017140340 and 07032017140312.

I tried to do with find command but could not get any idea like how to proceed with all the logic with loop. I do not want to loop all the files as we will not archive this source direcotory

echo "Program Begin" 

for file in `find . -type f -name "*_I_*`
do
 echo "Inside Loop" $file
 # Process file
 if [ -f "$file" ]; then
 echo "File Name=" $file 
 fi
done

echo "Program End" 

Please help.

Thanks
Bharat

Create two dummy files: dummy1 and dummy2, with filetimes you want

#  syntax touch -t yyyymmddhhmm.ss
touch -t  201707031403.12 dummy1
touch -t  201707031403.40 dummy2

Now create a find command using filetimes and the other criteria

find . -type f -name "*_I_* -a \( -newer dummy1 -a ! -newer dummy2  \) -exec ls -l {} \;

Run that and see if it gave you what you want. You may have to tweak the time statements in touch When it looks good put it back in your loop.

1 Like

Hi Jim,

Thanks a lot for your reply.
In my case timestamp is already in the file name. so i just need to select the files which meets the date range. Lets say i have below files.

f1_1
f1_2
f1_3
f1_4
f1_5

and if my input is 2 and 4. I should get the files 2,3 and 4. Something like between clause but with file name.

Thanks
Bharat

Will your range ever go over midnight or stretch over more than one day?

1 Like

To properly compare these filename we should change the DDMMYYYYHHMMSS format to YYYYMMDDHHMMSS - I have written a function ymd that I use below to compare filesnames to the supplied ranges:

echo "Program Begin"

from=07032017140340
to=07032017140312


# Convert DDMMYYYYHHMMSS to YYYYMMDDHHMMSS
ymd() {
    d=${1%????????????}
    m=${1#??}
    y=${1#????}
    m=${m%??????????}
    y=${y%??????}
    printf "%s" "$y$m$d${1#????????}"
}

from=$(ymd "$from")
to=$(ymd "$to")

find . -type f -name "ABC*_I_*" -print | while read file
do
    [ "$(ymd "${file##*_}") \> "$from" ] && continue
    [ "$(ymd "${file##*_}") \< "$to" ] && continue
    echo "File Name=" $file
done

echo "Program End"
1 Like

Hi Chubler,

Thanks for your reply.
I have the flexibility of change the DDMMYYYYHHMMSS format to YYYYMMDDHHMMSS. And yes it makes sense. I will make this change. But in the below code is there any way we can loop the date range first and then loop for the other condition, So most of the file get filters in first loop only.

find . -type f -name "ABC*_I_*" -print | while read file
do
    [ "$(ymd "${file##*_}") \> "$from" ] && continue
    [ "$(ymd "${file##*_}") \< "$to" ] && continue
    echo "File Name=" $file
done

I am not sure if unix stores any file creation date in server(Not the actual file creation date), even if i can filter using that date range also..it will be ok

Please help.

Thanks
Bharat

The standards don't have a file creation date in the stat structure, but some filesystem types do store that data. IOf your files are on are a filesystem that stores a creation timestamp AND your operating system's code supporting that filesystem type maintains that data, the find utility on your operating probably has a primary like -atime , -ctime , and -mtime for creation dates.

If the find man page on your system doesn't have a primary to check creation timestamp or your files are stored on a filesystem type that doesn't maintain that data AND you haven't changed the mode of your files since you created them AND you wrote all of the data into them that they currently contain immediately after creating the files, then find 's -ctime primary is probably sufficient for your needs. (The -ctime primary would be showing you the time at which data was last written into the file.)

1 Like

Hi Don,

Thank you.
Would be helpful if you can provide an example to use find -ctime. I need to lst the file which created from 06-MAR-2017 to 08-MAR-2017.

$ find . -ctime ABC_P_070317.txt
find: Specify a decimal integer for -ctime
Usage: find [-H | -L] path-list [predicate-list]

Thanks
Bharat

Isn't that error message self explaining?

As the -ctime argument specifies an interval of n*24h (counted from NOW) and not an absolute date, the command depends on the date/time it is run for today, 9.3.2017, it looked like

find . -ctime +0 -ctime -2 -name "ABC_P_*.txt"

(but cf man find for peculiarities). To specify intervals less than a day, consider the -cmin test.

1 Like

When you want to specify a range of times that is related to the start of a day instead of something that is a multiple of 24 hours from the time when you run your script, also consider using touch to create files with the starting and ending timestamps and using find 's -newer primary a couple of times...

trap 'rm -f /tmp/start.$$ /tmp/end.$$' 0
touch -t 201703060000 /tmp/start.$$
touch -t 201703090000 /tmp/end.$$
find . -newer /tmp/start.$$ ! -newer /tmp/end.$$ -name 'ABC*' -name '*_I_*'
1 Like

Thank you Don and Rubi. I am working on the solution based on your inputs. will post the code once its ready.

Thanks
Bharat