Batch rename selected wave and folder names

It can get very tedious if you have lots of waves or folders where you want to delete or replace the same part of the name manually. Here is a rudimentary script which lets you replace or append a string in the names of all waves/folders which are selected in the Data Browser. A prompt pops up which asks for the part of the name to be replaced. I have two drop-in escape codes 'pre' and 'suf' which just prepends or appends the string inserted in "With this". If you just want to delete parts of the name simply leave "With this" empty. This script has served me very well so far. At some point I hope there will be a full batch renamer in Igor, though.

EDIT: Added support for recursive sub-folder renaming and the option to copy with the new name instead of renaming.

Function QuickRenameWrapper()
    String this
    String withthis
    Variable overwrite = 0
    Prompt this, "Replace this (insert: pre = prepend; suf = append): "
    Prompt withthis, "With this: "
    Prompt overwrite, "Keep original?", popup "No;Yes, try to copy item;Yes, copy and overwrite;"
    DoPrompt "Replace Part of the Name", this, withthis, overwrite
    if (V_Flag)
        return -1
    endif
   
    String name = ""
    Make/free/T/N=0 selection
    Make/free/N=0 sortorder
    Variable index=0
    do
        name = GetBrowserSelection(index)
        if (strlen(name) <= 0)
            break
        endif
        selection[numpnts(selection)] = {name}
        sortorder[numpnts(sortorder)] = {ItemsInList(name,":")}
        index+=1
    while(1)
    Sort/R sortorder, selection
   
    String namelist
    wfprintf namelist, "%s;", selection
   
    QuickRename(this, namelist, withthis, copy=(overwrite-1))
End

Function QuickRename(String this, String namelist, String withthis, [Variable copy])
   
    Variable copyItem = 0   // copy: 0 = don't keep original; 1 = try copy but don't overwrite; 2 = copy and overwrite
    if(!ParamIsDefault(copy))
        copyItem = copy
    endif
   
    Variable index
    for (index = 0; index < ItemsInList(namelist); index += 1)
        String NewName = "", OldName = "", infolder = ""
        Variable isWave = 1
       
        String name = StringFromList(index,namelist)
        Wave/Z work = $name
        if (!WaveExists(work))      // is folder
            OldName = ParseFilePath(0, name, ":", 1, 0)
            infolder = ParseFilePath(1, name, ":", 1, 0)
            isWave = 0
        else
            OldName = nameofwave(work)
        endif
       
        if (StringMatch(this,"pre") == 1)
            NewName = withthis+OldName
        elseif (StringMatch(this,"suf") == 1)
            NewName = OldName+withthis
        else
            NewName = ReplaceString(this,OldName,withthis)
        endif
       
        if (isWave)
            Wave/Z test = $(SelectString(strlen(infolder),"root:",infolder)+NewName)
            if (copyItem == 2)
                Duplicate/O $Name, $NewName
            elseif (copyItem == 1)
                if (WaveExists(test) == 0)
                    Duplicate $Name, $NewName
                endif
            else
                if (WaveExists(test) == 0)
                    Rename $Name, $NewName
                endif
            endif
        else
            NewName = PossiblyQuoteName(ReplaceString("'",NewName,""))
            if (copyItem == 2)
                DuplicateDataFolder/O=3 $(infolder+OldName), $(infolder+NewName)
            elseif (copyItem == 1)
                DFREF testDir = $(infolder+NewName)
                if (DataFolderRefStatus(testDir) == 0)
                    DuplicateDataFolder $(infolder+OldName), $(infolder+NewName)
                endif
            else
                KillDataFolder/Z $(infolder+NewName)
                DFREF testDir = $(infolder+NewName)
                if (DataFolderRefStatus(testDir) == 0)
                    RenameDataFolder $(infolder+OldName), $(ReplaceString("'",NewName,""))
                endif
            endif
        endif
       
    endfor
End

 

QuickRename.ipf

There is an alternative to using this function that might work well in many situations.

You would select the data folders you want to rename, then click the Execute Cmd... button in the Data Browser. In the dialog, enter a command such as:

RenameDataFolder %s, %s_suffix

Then make sure the "Execute for each selected item" radio is checked. Then click the OK button.

If you were selecting waves and data folders you would need to call a user defined function to do the renaming since there isn't a built-in operation that can rename both waves and data folders.

Yes, I think the closest thing for waves would be:

Rename %s, $ReplaceString(this,NameOfWave(%s),withthis)

But this lacks robustness, since Rename is not able to overwrite anything. Above code puts both cases + some error handling and minimal GUI in a nice package for convenience. Is there a chance that the official Rename Objects function in Igor is expanded at some point to allow for batch renaming functionality (like search and replace or template rename)? 

I wrote a GUI that is a bit like Igor's Rename window, here. Might be easy to turn it into a batch renamer. It's a bit primitive compared with the built in dialogs, but for simple tasks it can be a starting point.

If there were a fully functional embedded object browser, like the one in the rename dialog, available as a panel control that would make things much easier. Maybe that already exists in Igor 9?

In reply to by tony

If there were a fully functional embedded object browser, like the one in the rename dialog, available as a panel control that would make things much easier. Maybe that already exists in Igor 9?

No, there's nothing like that in IP9 and probably never will be. Controls in panels are completely separate beasts from the things you might call controls (we call them widgets) in dialogs. It would be a truly massive amount of work to add an object browser control that could be used in panels. There is always the possibility of using the modal data browser for these types of situations. It's not perfect, but in some situations it's a lot nicer than using the wave selection package we ship with Igor.

That answer sounds familiar. I suspect it's not the first time I have asked :)

There are pros and cons to both modal data browser and wave selector 'widget' (which i guess is not a widget in the sense above), but between them they usually provide enough options to get the job done.

Tony, your normalize panel has indeed some nice ingredients for programming a batch rename GUI. I will have it on my list for a possible future project when I have more time to spare. 

@chozo: Your code seems to do the job or? The only thing I'm missing is descending into datafolder recursively and having an option to choose between not-overwriting and overwriting.

Hi Thomas, yes the code is doing the most simple tasks just fine. What would be nice, however, is a feature rich batch rename tool with something like multiple replacements in one go, a nice template generator to rename things with info from the wave notes or wave info and numbers / dates or even reshuffling of name parts. This would take a lot of time to put together but is in principle easy to do.

You are right that non-overwriting and recursive renaming would be an useful addition. I will look into that.

OK, I have updated the snipped now (see first post). I didn't do exhaustive testing, so please let me know if there is something wrong.

@chozo

something for you to test:

[edit: see below for updated version]

Tony,

Wow, so you have already put together a first GUI. I had a quick look at it. Do you want to open your own snippet or project page or should we discuss here? I found a few glitches, but I did not look at the code long enough to understand every part yet.

Thanks! I am currently completely overloaded with work, but may hack away at it when I get the time to code again.

Forum

Support

Gallery

Igor Pro 8

Learn More

Igor XOP Toolkit

Learn More

Igor NIDAQ Tools MX

Learn More