Globbing in Igor Pro
kobayashi
Glob returns the path names of all objects matching pattern as a text wave, where "objects" means waves, global variables, global string and data folders.
- * can match any string of characters not containing :
- ** matches any string of characters containing :
Examples
+ root (current folder)
+ folder1
+ subfolder1
- V_flag
- subfolder2
+ folder2
- subfolder1
- subfolder2
glob("root:folder*") //-> {"root:folder1", "root:folder2"}
glob("root:**1") //-> {"root:folder1", "root:folder1:subfolder1", "root:folder2:subfolder1"}
glob(":**:V_flag") // -> {":folder1:subfolder1:V_flag"}
glob("root:**1") //-> {"root:folder1", "root:folder1:subfolder1", "root:folder2:subfolder1"}
glob(":**:V_flag") // -> {":folder1:subfolder1:V_flag"}
Code
#pragma rtGlobals=3 // Use modern global access method and strict wave access.
#pragma ModuleName = glob
#pragma version = 0.1
Function/WAVE glob(pattern)
String pattern
if(StringMatch(pattern, "root:*")) // absolute path
WAVE/T buffer = glob_("root:", pattern[5, inf])
elseif(StringMatch(pattern, ":*")) // relative path (beginning with :)
WAVE/T buffer = glob_(":", pattern[1, inf])
else // relative path (others)
WAVE/T buffer = glob_("", pattern)
buffer = (buffer)[1, inf] // glob_ adds : to represent a relative path
endif
// glob does not add ending : for folders unless the user adds :
if(StringMatch(pattern "*:"))
buffer = RemoveEnding(buffer, ":") + ":"
endif
return buffer
End
// Returns a text wave containing matched pathnames
static Function/WAVE glob_(root, pattern)
String root // a relative or absolute pathname as a root
String pattern // a maching pattern using * or **
// the root pathname must end with :
root = RemoveEnding(root, ":") + ":"
Make/FREE/T/N=0 buffer
// leaf / inner node of matching algorithm
if(ItemsInList(pattern, ":") < 2)
// leaf node of matching algorithm
// data folder only or not
if(StringMatch(pattern, "*:"))
Concatenate/T/NP {MatchedFolders(root, RemoveEnding(pattern, ":"))}, buffer
else
Concatenate/T/NP {MatchedObjects(root, pattern), MatchedFolders(root, pattern)}, buffer
endif
else
// inner node of matching algorithm
// refers a parent folder (using ::) or not
if(StringMatch(pattern, ":*"))
// matching with a parent path
root += SelectString(StringMatch(root, "root:"), ":", "") // the root of root: is root: itself
Concatenate/T/NP {glob_(root, pattern[1, inf])}, buffer
else
// matching recursively
WAVE/T folders = MatchedFolders(root, StringFromList(0, pattern, ":"))
Variable i
for(i = 0; i < DimSize(folders, 0); i += 1)
Concatenate/T/NP {glob_(folders[i], pattern[strsearch(pattern, ":", 0)+1, inf])}, buffer
endfor
endif
endif
// global matching pattern ** is equivalent to *:**
if(strsearch(StringFromList(0, pattern, ":"), "**", 0) >= 0)
Concatenate/T/NP {glob_(root, ReplaceString("**", pattern, "*:**", 0, 1))}, buffer
endif
return buffer
End
static Function/WAVE MatchedFolders(root, pattern)
String root, pattern
root = RemoveEnding(root, ":") + ":"
Make/FREE/T/N=(DataFolderExists(root) ? CountObjects(root, 4) : 0) folders = PossiblyQuoteName(GetIndexedObjName(root, 4, p))
Extract/T/O folders, folders, Match(folders, pattern)
folders = root + folders
return folders
End
static Function/WAVE MatchedObjects(root, pattern)
String root, pattern
root = RemoveEnding(root, ":") + ":"
Make/FREE/T/N=(DataFolderExists(root) ? CountObjects(root, 1) : 0) wavs = GetIndexedObjName(root, 1, p)
Make/FREE/T/N=(DataFolderExists(root) ? CountObjects(root, 2) : 0) vars = GetIndexedObjName(root, 2, p)
Make/FREE/T/N=(DataFolderExists(root) ? CountObjects(root, 3) : 0) strs = GetIndexedObjName(root, 3, p)
Make/FREE/T/N=0 objects
Concatenate/T/NP {wavs, vars, strs}, objects
Extract/T/O objects, objects, Match(objects, pattern)
objects = root + objects
return objects
End
static Function Match(str, pattern)
String str, pattern
// A pattern matches both of normal a name and a free name.
// For example, "*1" matches both of "folder1" and "'folder 1'"
//
// If a pattern is beginning with !, the return value of StringMatch is reveresed.
// Because ! has no meaning for the pathname-matching, compare (" " + str) with (" " + pattern) here.
if(StringMatch(str, "'*'"))
return StringMatch(" " + RemoveEnding(str[1, inf], "'"), " " + pattern) || StringMatch(" " + str, " " + pattern)
else
return StringMatch(" " + str, " " + pattern)
endif
End
#pragma ModuleName = glob
#pragma version = 0.1
Function/WAVE glob(pattern)
String pattern
if(StringMatch(pattern, "root:*")) // absolute path
WAVE/T buffer = glob_("root:", pattern[5, inf])
elseif(StringMatch(pattern, ":*")) // relative path (beginning with :)
WAVE/T buffer = glob_(":", pattern[1, inf])
else // relative path (others)
WAVE/T buffer = glob_("", pattern)
buffer = (buffer)[1, inf] // glob_ adds : to represent a relative path
endif
// glob does not add ending : for folders unless the user adds :
if(StringMatch(pattern "*:"))
buffer = RemoveEnding(buffer, ":") + ":"
endif
return buffer
End
// Returns a text wave containing matched pathnames
static Function/WAVE glob_(root, pattern)
String root // a relative or absolute pathname as a root
String pattern // a maching pattern using * or **
// the root pathname must end with :
root = RemoveEnding(root, ":") + ":"
Make/FREE/T/N=0 buffer
// leaf / inner node of matching algorithm
if(ItemsInList(pattern, ":") < 2)
// leaf node of matching algorithm
// data folder only or not
if(StringMatch(pattern, "*:"))
Concatenate/T/NP {MatchedFolders(root, RemoveEnding(pattern, ":"))}, buffer
else
Concatenate/T/NP {MatchedObjects(root, pattern), MatchedFolders(root, pattern)}, buffer
endif
else
// inner node of matching algorithm
// refers a parent folder (using ::) or not
if(StringMatch(pattern, ":*"))
// matching with a parent path
root += SelectString(StringMatch(root, "root:"), ":", "") // the root of root: is root: itself
Concatenate/T/NP {glob_(root, pattern[1, inf])}, buffer
else
// matching recursively
WAVE/T folders = MatchedFolders(root, StringFromList(0, pattern, ":"))
Variable i
for(i = 0; i < DimSize(folders, 0); i += 1)
Concatenate/T/NP {glob_(folders[i], pattern[strsearch(pattern, ":", 0)+1, inf])}, buffer
endfor
endif
endif
// global matching pattern ** is equivalent to *:**
if(strsearch(StringFromList(0, pattern, ":"), "**", 0) >= 0)
Concatenate/T/NP {glob_(root, ReplaceString("**", pattern, "*:**", 0, 1))}, buffer
endif
return buffer
End
static Function/WAVE MatchedFolders(root, pattern)
String root, pattern
root = RemoveEnding(root, ":") + ":"
Make/FREE/T/N=(DataFolderExists(root) ? CountObjects(root, 4) : 0) folders = PossiblyQuoteName(GetIndexedObjName(root, 4, p))
Extract/T/O folders, folders, Match(folders, pattern)
folders = root + folders
return folders
End
static Function/WAVE MatchedObjects(root, pattern)
String root, pattern
root = RemoveEnding(root, ":") + ":"
Make/FREE/T/N=(DataFolderExists(root) ? CountObjects(root, 1) : 0) wavs = GetIndexedObjName(root, 1, p)
Make/FREE/T/N=(DataFolderExists(root) ? CountObjects(root, 2) : 0) vars = GetIndexedObjName(root, 2, p)
Make/FREE/T/N=(DataFolderExists(root) ? CountObjects(root, 3) : 0) strs = GetIndexedObjName(root, 3, p)
Make/FREE/T/N=0 objects
Concatenate/T/NP {wavs, vars, strs}, objects
Extract/T/O objects, objects, Match(objects, pattern)
objects = root + objects
return objects
End
static Function Match(str, pattern)
String str, pattern
// A pattern matches both of normal a name and a free name.
// For example, "*1" matches both of "folder1" and "'folder 1'"
//
// If a pattern is beginning with !, the return value of StringMatch is reveresed.
// Because ! has no meaning for the pathname-matching, compare (" " + str) with (" " + pattern) here.
if(StringMatch(str, "'*'"))
return StringMatch(" " + RemoveEnding(str[1, inf], "'"), " " + pattern) || StringMatch(" " + str, " " + pattern)
else
return StringMatch(" " + str, " " + pattern)
endif
End
Forum
Support
Gallery
Igor Pro 9
Learn More
Igor XOP Toolkit
Learn More
Igor NIDAQ Tools MX
Learn More