2

Problem: I have a bunch of files that were downloaded from an org. Halfway through their data directory the org changed the naming convention (reasons unknown). I am looking to create a script that will take the files in a directory and rename the file the same way, but simply "go back one day".

Here is a sample of how one file is named: org2015365_res_version.asc

What I need is logic to only change the year day (2015365) in this case to 2015364. This logic needs to span a few years so 2015001 would be 2014365.

I guess I'm not sure this is possible since its not working with the current date so using a module like datetime does not seem applicable.

Partial logic I came up with. I know it is rudimentary at best, but wanted to take a stab at it.

# open all files
all_data = glob.glob('/somedir/org*.asc')

# empty array to be appended to
day = []
year = []

# loop through all files
for f in all_data:
    # get first part of string, renders org2015365
    f_split = f.split('_')[0]
    # get only year day - renders 2015365
    year_day = f_split.replace(f_split[:3], '')
    # get only day - renders 365
    days = year_day.replace(year_day[0:4], '')
    # get only year - renders 2015
    day.append(days)
    years = year_day.replace(year_day[4:], '')
    year.append(years)
    # convert to int for easier processing 
    day = [int(i) for i in day]
    year = [int(i) for i in year]

    if day == 001 & year == 2016:
        day = 365
        year = 2015
    elif day == 001 & year == 2015:
        day = 365
        year = 2014
    else:
        day = day - 1

Apart from the logic above I also came across the function below from this post, I am not sure what would be the best way to combine that with the partial logic above. Thoughts?

import glob
import os


def rename(dir, pattern, titlePattern):
    for pathAndFilename in glob.iglob(os.path.join(dir, pattern)):
        title, ext = os.path.splitext(os.path.basename(pathAndFilename))
        os.rename(pathAndFilename,
                  os.path.join(dir, titlePattern % title + ext))

rename(r'c:\temp\xx', r'*.doc', r'new(%s)')

Help me, stackoverflow. You're my only hope.

Community
  • 1
  • 1
Nikolai
  • 243
  • 3
  • 15

2 Answers2

1

You can use datetime module:

#First argument - string like 2015365, second argument - format
dt = datetime.datetime.strptime(year_day,'%Y%j')
#Time shift
dt = dt + datetime.timedelta(days=-1)
#Year with shift
nyear = dt.year
#Day in year with shift
nday = dt.timetuple().tm_yday
Stanislav Ivanov
  • 1,854
  • 1
  • 16
  • 22
0

Based on feedback from the community I was able to get the logic needed to fix the files downloaded from the org! The logic was the biggest hurdle. It turns out that the datetime module can be used, I need to read up more on that.

I combined the logic with the batch renaming using the os module, I put the code below to help future users who may have a similar question!

# open all files
all_data = glob.glob('/some_dir/org*.asc')

# loop through
for f in all_data:
    # get first part of string, renders org2015365
    f_split = f.split('_')[1]
    # get only year day - renders 2015365
    year_day = f_split.replace(f_split[:10], '')
    # first argument - string 2015365, second argument - format the string to datetime
    dt = datetime.datetime.strptime(year_day, '%Y%j')
    # create a threshold where version changes its naming convention
    # only rename files greater than threshold
    threshold = '2014336'
    th = datetime.datetime.strptime(threshold, '%Y%j')
    if dt > th:
        # Time shift - go back one day
        dt = dt + datetime.timedelta(days=-1)
        # Year with shift
        nyear = dt.year
        # Day in year with shift
        nday = dt.timetuple().tm_yday
        # rename files correctly
        f_output = 'org' + str(nyear) + str(nday).zfill(3) + '_res_version.asc'
        os.rename(f, '/some_dir/' + f_output)
    else:
        pass
Nikolai
  • 243
  • 3
  • 15