How to read a number from filename and output to a new wave

Hello,

I have several x and y spectral data files that were collected over time, and their timestamp is in the filename. For example, the files are named xspec1.asc, xspec3.asc, xspec4.asc and so on. The timestamps are not exactly every second but vary. Is there a way to read these filenames and extract the timestamp numbers into a separate file, say called time?

I've been looking at the various available functions - RemoveEnding will work to take out the ".asc", but I'm not sure how to extract the number, reject the "xspec", and output to a new wave. Will StringFromList or sscanf work?

Thanks

Rahul
One way is to use regular expressions. For example:
function test()
    string sTest="xspec3.asc"
    string sNum
    SplitString/E="([[:digit:]]+)" sTest, sNum
    print sNum
end

This just extracts the first set of digits it can find (in sTest) into the result string (sNum).
HTH,
Kurt
rahulsrao wrote:
I've been looking at the various available functions - RemoveEnding will work to take out the ".asc", but I'm not sure how to extract the number, reject the "xspec", and output to a new wave. Will StringFromList or sscanf work?


In addition to KurtB's solution, you could use string indexing to extract the part of the string of interest.

Execute the following from the Igor command line read more about string indexing from the help file: DisplayHelpTopic "String Indexing".

After applying RemoveEnding you should have a string like xspecNNN, where NNN is the time stamp.

Any part of a string can be accessed using string indexing. For example:

print "xspec100"[5,inf]

will print "100". That is, it will print the part of the string from the 5th character to the end of the string. Indexing is 0 based -- the first character is at position "0", and "inf" is a convenient way to specify the end of the string. You could also use "strlen" to get the exact string length. Position of the final character in the string is the value reported by strlen less 1. Any contiguous part of the string can be accessed using appropriate starting and ending values inside the brackets.

Use "str2num" to convert the timestamp from a string to a numeric value.

Variable nTimeStamp = str2num( "xspec100"[5,inf] )

will assign the timestamp value ("100") to the numeric variable nTimeStamp.

Hope this helps.
Thanks for the help!

Now I need to figure out how to convert the string into a datapoint in a wave so that I can read off the filenames from all of my files and populate a wave ....

Haven't had much luck finding the solution in the help files.

Rahul
To convert the string to a number use

str2num(theString).

and set to a point in your wave such as

yourWave[index] = str2num(theString).
OK I've tried all suggestions, but keep getting an error. Can someone please debug this function -
When I run it, the wave Times is created with the right number of rows, but all values are 0 instead of the number following "yspec", i.e. 1, 3, 4, etc.

Rahul

Function timestamp ()
   
    string List
    variable i, n
   
    List = Wavelist ("yspec*",";","")
    n = ItemsInList (List)
    Make/n=(n)/o Times
         
    for (i=0; i<n; i+=1)
        Times[i]=str2num (list[5,inf])
    endfor
   
end
Replace this:
Times[i]=str2num (list[5,inf])


with this:
String name = StringFromList(i, list)
Times[i] = str2num(name[5,inf])       // This is hard to debug


For easier debugging, change it to this:
String name = StringFromList(i, list)
String temp = name[5,inf]                // This is easy to debug
Times[i] = str2num(temp)


Finally, I'm not sure if this use of INF is safe or not. To be safe, change it to this:
String name = StringFromList(i, list)
Variable len = strlen(name)
String temp = name[5,len]
Times[i] = str2num(temp)


Or use sscanf, like this:
String name = StringFromList(i, list)
Variable num
sscanf name, "yspec%d", num
Times[i] = num


hrodstein,

Thank you again! splitting up the commands does make it a lot easier to debug.

Thanks

Rahul