1

I am working within an ESRI ArcGIS environment. I have a folder full of .xyz files that are named to a specific old file format such as 2014516_MS_005.xyz I want to be able to loop through the whole folder and rename each file to a new format such as MS_e1614.xyz. As you can see there is alot of string displacement and new characters introduced.

Can you guys n gals point me to the right direction if there is already a resource similar to this question?

Here is what i have so far.

import os

survey_type = ['MB','SB']

#File path for directory of interest
folder = r'C:\Data Management\Implementation\xyz_data'

#List of all files in set directory
file_list = os.listdir(folder)
print file_list
  • You mention ArcGIS but this is a pure Python question and so is best researched/asked at Stack Overflow. – PolyGeo Jan 30 '15 at 20:30
  • 1
    Even though you're manipulating spatial data, this is more of a pure IT task, better suited to SO – Vince Jan 30 '15 at 20:33
  • 1
    I disagree that this question is best suited for SO. The fact that ArcGIS has a Python tool called Rename_management () should be a good argument for keeping this question on GIS SE. – Aaron Jan 30 '15 at 20:46
  • 2
    i would be surprised if this wasn't an almost typical GIS data management problem. – user40720 Jan 30 '15 at 20:56
  • Agreed @user40720, for me this is a daily task in wrangling various spatial data formats. – Aaron Jan 30 '15 at 21:03
3

There are several ways to do this, but maybe the simplest is to use os.rename(). Loop through file_list and rename according to whatever algorithm you're using. For you example (untested, try on a copy of your data first):

for file in file_list:
    name_parts = file.split('_') # = ['2014516', 'MS', '005.xyz']
    pre = '_'.join([name_parts[1], 'e']) # = 'MS_e'
    mid = name_parts[0][-2:] # = '16'
    suf = name_parts[0][2:4] # = '14'
    ext = '.xyz'
    new_file =  ''.join([pre, mid, suf, ext])
    try:
        os.rename(file, new_file)
    except Exception as e:
        print('Exception is: {0}'.format(e)

This is independent of Arc. As stated above, there are other methods, but this is one.

  • well explained. i am testing it out now – user40720 Jan 30 '15 at 20:47
  • i keep getting error when i write the new file. – user40720 Jan 30 '15 at 20:54
  • Well, what is the error? I added a try block above, should help see the error. – recurvata Jan 30 '15 at 20:57
  • I had to save the script in same directory as the folder that carried the xyz files. I also added an endswith if statement. – user40720 Jan 30 '15 at 21:16
  • You could add the directory path in as well, that should take care of the script having to be in the same folder. .endswith is a good check. If all your files end in .xyz, it's not necessary, but doesn't hurt either. If you want to rename according to a different algorithm, you'd have to figure that out. Both my and @Chris Hogan are assuming a consistent scheme according to the example you gave. – recurvata Jan 30 '15 at 21:22
2

I am a little unclear about how the original filename will translate to the new file name, but here is a python snippet that should put you in the right direction:

import os

for file in os.listdir('.'):
    if file.endswith('.xyz'):
        a = file.split('_')
        ## for months 1 to 9
        if len(a[0]) == 7:
            print 'working on ' + a[1] + '_e' + a[0][5:7] + a[0][2:4] + '.xyz'
            os.rename(file, a[1] + '_e' + a[0][5:7] + a[0][2:4] + '.xyz')
        ## for months 10, 11, 12
        if len(a[0]) == 8:
            print 'working on ' + a[1] + '_e' + a[0][6:8] + a[0][2:4] + '.xyz'
            os.rename(file, a[1] + '_e' + a[0][6:8] + a[0][2:4] + '.xyz')

The code above will need to be saved in to the directory with the files you want to rename. If you want to save this python snippet somewhere else, you will need to update the directory from '.' to the location of the files to rename.

This file specifically builds an array of all files in the target directory (the array is named file).

For every item in the array, if it ends with '.xyz', it will split the string representation of the file name by the underscore.

Each filename is now an array consisting of the date, state abbreviation, and the numbers after the state. You will see in the above example I cherry pick the state abbreviation, concatenate '_e', then concatenate just the last two digits of the year and what appears to be the day number, finally concatenating the extension name.

  • 1
    The if block above should be indented. Maybe just a quirk of the formatting. – recurvata Jan 30 '15 at 20:41
  • What if i wanted to split it by other parameters? Also, what if i wanted to change a specific character from the beginning of the string on one filename and towards the end of the string on the new filename? – user40720 Jan 30 '15 at 21:11
  • You can split by any characters you want. For example splitting the string 'cat_rat+bird', if you split by the underscore you would have an array of ['cat','rat+bird']. If you split by the 'a' characters, you would have ['c','t_r','t+bird']. When you split a string in to an array, for example myArray = ['c','t_r','t+bird'], you can access each item using square brackets and a number for the index positon. myArray[0] equals 'c', myArray[2] equals 't+bird'. You can then re-arrange them by concatenating them in whatever order you want. myArray[2]+myArray[0] == 't+birdc' – Chris Hogan Jan 30 '15 at 21:22
  • If you need to do different things in different places, you will need an ever more elaborate set of 'if' statements. For example, if you know your survey types are at a specific position or are surrounded by specific things you can split by, you can said "if arrayItem[<survey_item_position>] == 'SB':" do something different than "if arrayItem[<survey_item_position>] == 'MB':" – Chris Hogan Jan 30 '15 at 21:25
  • this hits precisely. I'm going to have to try it out. – user40720 Jan 30 '15 at 21:28

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.