A number of functions are available for working with string variables. They are described in the following sections. (See also the section later in this chapter, "PLOT+ string editing tools" for more ways to manipulate strings.)
7.2.1 STRCMP(string1, string2)
string1: string
string2: string
result: real
Compares two strings or string arrays. It computes the numerical difference in ASCII character value for the first character that differs between the two strings returns a number, > 0 if string1 > string2, 0 if they are equal and < 0 if string1 < string2.
Examples:
yes? list strcmp("b",{"a","b","c"}) VARIABLE : STRCMP("b",{"a","b","c"}) SUBSET : 3 points (X) 1 / 1: 1.000 2 / 2: 0.000 3 / 3: -1.000 yes? list strcmp({"a","b","c"},YSEQUENCE({"a","b","c"})) VARIABLE : STRCMP({"a","b","c"},YSEQUENCE({"a","b","c"})) SUBSET : 3 by 3 points (X-Y) 1 2 3 1 2 3 1 / 1: 0.000 1.000 2.000 2 / 2: -1.000 0.000 1.000 3 / 3: -2.000 -1.000 0.000 yes? let a = "a longer string" yes? list strcmp (a,"a longer stringg") VARIABLE : STRCMP (a,"a longer stringg") -103.0
string1: string
result: real
Returns the length of the string-type variable passed in string string1
Example:
yes? LET myfile = "/home/e1/data/coads_climatology.nc" yes? LIST STRLEN(myfile) VARIABLE : STRLEN(MYFILE) 34.00 yes? LET svar = {"aa", "bbb", "cccc"} yes? LIST strlen(svar) VARIABLE : STRLEN(SVAR) SUBSET : 3 points (X) 1 / 1: 2.000 2 / 2: 3.000 3 / 3: 4.000
7.2.3 UPCASE(string1)
string1: string
result: string
Returns the string passed in string variable string1 in all upper case characters
yes? LET svar = {"aa", "bbb", "cccc"} yes? list upcase(svar) VARIABLE : UPCASE(SVAR) SUBSET : 3 points (X) 1 / 1:"AA" 2 / 2:"BBB" 3 / 3:"CCCC"
7.2.4 DNCASE(string1)
string1: string
result: string
Returns the string passed in string string1 in all lower case characters
yes? LET svar = {"Boulder", "Seattle", "San Francisco"} yes? LIST DNCASE(svar) VARIABLE : DNCASE(SVAR) SUBSET : 3 points (X) 1 / 1:"boulder" 2 / 2:"seattle" 3 / 3:"san francisco"
7.2.5 STRINDEX(string1, substring)
string1: string
substring: string
result: real
Locate first occurrence of substring in string1. Returns a 0 if substring doesn't exist in string1. If substring contains a zero-character string (i.e. ""), the function returns 1. The function is case-specific.
yes? LET myfile = "/home/e1/data/coads_climatology.nc" yes? LIST STRINDEX(myfile, "coads") VARIABLE : STRINDEX(MYFILE, "coads") 15.00 yes? LIST STRINDEX(myfile, "COADS") VARIABLE : STRINDEX(MYFILE, "COADS") 0.0000
7.2.6 STRRINDEX(string1, substring)
string1: string
substring: string
result: real
Locates last occurence of string substring in string1. Returns a 0 if substring doesn't exist in string1. If substring contains a zero character string (i.e. ""), the function returns the length of string1
yes? LET myfile = "/home/e1/data/coads_climatology.nc" yes? LIST STRRINDEX(myfile, "/") VARIABLE : STRRINDEX(MYFILE, "/") 14.00
7.2.7 SUBSTRING(string1, offset, len)
string1: string
offset: integer
len: integer
result: string
Returns substring of length len from string string1 beginning from character offset in string1. If offset is 0, or if offset is greater than the length of string string1, a NULL value is returned. If length len exceeds the total length of string string1, the value of string string1 starting at offset is returned.
yes? LET myfile = "/home/e1/data/coads_climatology.nc" yes? LET ns = STRRINDEX(myfile, "/") VARIABLE : STRRINDEX(MYFILE, "/") 14.00 yes? LET path = SUBSTRING(myfile, 1, ns) yes? LIST path VARIABLE : SUBSTRING(MYFILE, 1, NS) "/home/e1/data/"
7.2.8 STRCAT(string1, str2)
string1: string
string2: string
result: string
Append a copy of string string2 onto string string1. As with other functions, the rules of conformability apply to the arguments.
yes? LET s1 = "hello " yes? LET s2 = "world" yes? LIST STRCAT (s1, s2) VARIABLE : STRCAT (S1, S2) "hello world" yes? LET s1 = "hello " yes? LET svar = {"Boulder", "Seattle", "San Francisco"} yes? LIST STRCAT (s1, svar) VARIABLE : STRCAT(S1, SVAR) SUBSET : 3 points (X) 1 / 1:"hello Boulder" 2 / 2:"hello Seattle" 3 / 3:"hello San Francisco"
7.2.9 STRFLOAT(string1)
string1: string
result: real
Return float value of string string1
yes? LET pie = "3.14" yes? LIST STRFLOAT (pie)yes? list strfloat(pie) VARIABLE : STRFLOAT(PIE) 3.140
A: numeric variable
FMT: string, the Fortran format specification.
result: string
Convert numeric data to strings using the specified Fortran format.
Examples:
yes? SHOW FUNCTION floatstr FLOATSTR(A,FMT) Returns float converted to strings according to format specified A: Floating-point variable to convert FMT: Fortran format, in parentheses, e.g. "(F5.1)" (STRING) yes? LIST floatstr({3.14159,2.71828,10},"(f7.3)") VARIABLE : FLOATSTR({3.14159,2.71828,10},"(f7.3)") SUBSET : 3 points (X) 1 / 1:" 3.142" 2 / 2:" 2.718" 3 / 3:" 10.000"
yes? USE etopo60 yes? LIST floatstr(rose[y=60,x=-10:0], "(f6.0)") VARIABLE : FLOATSTR(ROSE[Y=60,X=-10:0], "(f6.0)") FILENAME : etopo60.cdf FILEPATH : /home/porter/tmap/ferret/linux/fer_dsets/data/ SUBSET : 10 points (LONGITUDE) LATITUDE : 59.5N 59.5N 150 9.5W / -29:"-1327." 8.5W / -28:"-1245." 7.5W / -27:" -869." 6.5W / -26:" -444." 5.5W / -25:" -260." 4.5W / -24:" -130." 3.5W / -23:" -93." 2.5W / -22:" -67." 1.5W / -21:" -90." 0.5W / -20:" -115."
yes? USE coads_climatology yes? LIST floatstr(sst[x=10:20,y=60,L=1], "(g8.3)") VARIABLE : FLOATSTR(SST[X=10:20,Y=60,L=1], "(g8.3)") FILENAME : coads_climatology.cdf FILEPATH : /home/porter/tmap/ferret/linux/fer_dsets/data/ SUBSET : 6 points (LONGITUDE) LATITUDE : 59N TIME : 16-JAN 06:00 59N 75 11E / -4:"3.36" 13E / -3:"" 15E / -2:"" 17E / -1:"2.32" 19E / 0:"2.69" 21E / 1:"2.90"
Notes:
1) The Fortran format in argument 2 must be a numeric format (as is the case for LIST/FORMAT). F, G, E, I, and D formats are allowed. "A" formats are not allowed. Prior to Ferret v6.95, Integer formats were not allowed.
In addition, zero-filled output may be requested using a modified F-format specifier. If F is followed by a 0, the result is zero-filled.
Examples:
yes? LIST FLOATSTR({3.14,2.72},"(I3)") VARIABLE : FLOATSTR({3.14,2.72},"(I3)") SUBSET : 2 points (X) 1 / 1:" 3" 2 / 2:" 2" yes? list FLOATSTR({3.14,2.72},"(I4.4)") VARIABLE : FLOATSTR({3.14,2.72},"(I4.4)") SUBSET : 2 points (X) 1 / 1:"0003" 2 / 2:"0002" yes? list FLOATSTR({3.14,2.72},"(F6.2)") VARIABLE : FLOATSTR({3.14,2.72},"(F6.2)") SUBSET : 2 points (X) 1 / 1:" 3.14" 2 / 2:" 2.72" yes? list FLOATSTR({3.14159,2.71828},"(F06.2)") VARIABLE : FLOATSTR({3.14159,2.71828},"(F06.2)") SUBSET : 2 points (X) 1 / 1:"003.14" 2 / 2:"002.72"
2) Missing data in the numeric variable is converted by FLOATSTR to the null string.
7.2.11 LABWID(string, charsize)
string: string, possibly including a font specification, and may include <NL> newline character
charsize: real
result: real
Returns the size in plot-page inches of the string. If a font is specified, it takes the size of characters in that font into account. If the string is a multi-line label, the result is computed for the longest line as it will appear on the plot page.
Examples:
! LABWID with two different character sizes, ! lowercase vs capitals, and the italics font yes? LIST/NOHEADER LABWID("abcdefg", .15) 0.8857 yes? LIST/NOHEADER LABWID("abcdefg", .10) 0.5905 yes? LIST/NOHEADER LABWID("ABCDEFG", .15) 0.9929 yes? LIST/NOHEADER LABWID("@IIabcdefg", .15) 1.0000 ! multi-line label: result is the length of the longest line yes? LIST/NOHEADER LABWID("abcdefg<NL>hi", .15) 0.8857 ! Make a plot, drawing one label after another. ! Use the italics font for the first label. yes? PLOT/VS/LINE/I=1:314 i*cos(i/20),i*sin(i/20) yes? LET firstlab = "@iiMy label" yes? LABEL/NOUSER 0, 3, -1, 0, .15, "`firstlab`" yes? LET wid = labwid("`firstlab`", .15) yes? LABEL/NOUSER `wid`, 3, -1, 0, .15, "@P4Second Label"
7.2.12 SPAWN command
The SPAWN command executes a Unix system command and returns the result in a string array. The syntax SPAWN:"command" inside a string array definition allows the output of a Unix command to be mixed with other strings.
SPAWN commands are disallowed when Ferret was started in secure mode with
> ferret -secure
Examples:
LET a = {"first.nc", SPAWN:"ls *.nc","last.nc"}
Say we want to check whether a file is in the directory. We do not want a null result, so start with a dummy string. If "myfile.nc" exists, there will be 2 entries in array a.
yes? LET a = {"dummy", SPAWN:"ls myfile.nc"} yes? LET nfiles = `a[i=@ngd]` yes? IF `nfiles EQ 2` THEN ...
7.2.12.1 SPAWN Function
The SPAWN function executes a Unix system command or set of commands, and returns the result in a string array. Each element of the result is a line of the output.
The SPAWN function is disallowed when Ferret was started in secure mode with
> ferret -secure
Examples:
yes? LET lengths = SPAWN("wc *.jnl") yes? LET who_where_when = SPAWN("whoami; pwd; date")
7.2.13 Algebraic operations with string variables.
A number of algebraic operations are available for string variables. They are described in the following sections.
7.2.13.1 Logical operators with strings
The operators EQ, LT, LE, ... can be applied to string variables and arrays. These operators are case-insensitive (functions will be provided later that are case-sensitive and include UPCASE, DNCASE)
Examples:
yes? LIST/NOHEAD {"a","b","c"} EQ {"A","B","C"} ! case insensitive 1 / 1: 1.000 2 / 2: 1.000 3 / 3: 1.000
yes? LIST/NOHEAD "b" GT {"a","b","c"} 1 / 1: 1.000 2 / 2: 0.000 3 / 3: 0.000
7.2.13.2 Shift transformation of string arrays
The shift transformation can be applied to string arrays.
For example:
yes? LET a = {"a","b","c","d"} yes? LIST a[i=@SHF] {"a","b","c","d"} shifted by 1 pts on X 1 / 1:"b" 2 / 2:"c" 3 / 3:"d" 4 / 4:"" yes? LIST a[i=@SHF:-1] {"a","b","c","d"} shifted by -1 pts on X 1 / 1:"" 2 / 2:"a" 3 / 3:"b" 4 / 4:"c"
7.2.13.3 Strings in IF-THEN-ELSE
IF condition THEN string_array1 ELSE string_array2
Example:
yes? LIST/NOHEAD IF {0,1} THEN "hello" ELSE "goodbye" 1 / 1:"goodbye" 2 / 2:"hello"
7.2.13.4 String concatenation with "+":
String variables may be concatenated with the XCAT, YCAT, ZCAT or TCAT functions.
This may also be done with the addition operator:
Examples:
yes? LET a = "good" + "bye" yes? LIST/NOHEAD YSEQUENCE({"now","then"})+", " + (if {0,1} THEN "hello"+", ") + "friend" 1 / 1:"now, friend" "now, hello, friend" 2 / 2:"then, friend" "then, hello, friend"
7.2.13.5 Strings as Function arguments
A few functions also take strings as arguments. String arguments must be enclosed in double quotes. For example, the TAX_DATESTRING allows a customized output precision, set by the last argument.
yes? list tax_datestring(date_list,t[gt=tax], "day")
SAMPLE* functions may take string or numerical arrays as arguments
Example:
yes? LIST/NOHEAD SAMPLEI({"a","b","c","d","e","f"},{3,2,,1}) 1 / 1:"c" 2 / 2:"b" 3 / 3:"" 4 / 4:"a" yes? LIST/NOHEAD SAMPLEJ(YSEQUENCE ({"a","b","c","d","e","f"}), {3,2,,1}) 1 / 1:"c" 2 / 2:"b" 3 / 3:"" 4 / 4:"a"
7.2.13.6 Regridding string arrays
The regridding transformations @ASN, @XACT, @NRST can be used with character data.
Examples:
yes? LET a = {spawn:"ls *.nc"} yes? LIST a {SPAWN:"ls *.nc"} 1 / 1:"d1.nc" 2 / 2:"d2.nc" 3 / 3:"d3.nc" 4 / 4:"d4.nc" 5 / 5:"d5.nc" 6 / 6:"d6.nc" 7 / 7:"d7.nc" yes? DEFINE AXIS/X=0.1:0.7:.1 xasn yes? LIST a[gx=xasn@ASN] {SPAWN:"ls *.nc"} regrid: 0.1 delta on X@ASN 0.1 / 1:"d1.nc" 0.2 / 2:"d2.nc" 0.3 / 3:"d3.nc" 0.4 / 4:"d4.nc" 0.5 / 5:"d5.nc" 0.6 / 6:"d6.nc" 0.7 / 7:"d7.nc" yes? DEFINE AXIS/X=1:6:.5 xxact yes: LIST a[gx=xxact@XACT] {SPAWN:"ls *.nc"} regrid: 0.5 delta on X@XACT 1 / 1:"d1.nc" 1.5 / 2:"" 2 / 3:"d2.nc" 2.5 / 4:"" 3 / 5:"d3.nc" 3.5 / 6:"" 4 / 7:"d4.nc" 4.5 / 8:"" 5 / 9:"d5.nc" 5.5 / 10:"" 6 / 11:"d6.nc" yes? DEFINE AXIS/X=1:6:.4 xnrst yes? LIST a[gx=xnrst@NRST] {SPAWN:"ls *.nc"} regrid: 0.4 delta on X@NRST 1 / 1:"d1.nc" 1.4 / 2:"d1.nc" 1.8 / 3:"d2.nc" 2.2 / 4:"d2.nc" 2.6 / 5:"d3.nc" 3 / 6:"d3.nc" 3.4 / 7:"d3.nc" 3.8 / 8:"d4.nc" 4.2 / 9:"d4.nc" 4.6 / 10:"d5.nc" 5 / 11:"d5.nc" 5.4 / 12:"d5.nc" 5.8 / 13:"d6.nc" 6.2 / 14:"d6.nc"
7.2.14 NetCDF input and output of string data
String variables can be input and output to netCDF files. In the file the string axis is the fastest moving dimension and all strings are the same length (equal to the maximum length of the strings being written). Extra character spaces are padded with nulls. If variable length strings are written out, then when read back they will again be variable length.
Example:
yes? SAVE/CLOBBER/FILE=test_string.cdf/HEADING=enhanced a[i=2:4]
7.2.15 Transformations on string data
The transformations @NGD and @NBD can be used to compute the number of valid and invalid strings. The null string is taken to be the "missing value" for string data.
yes? LET svar = {"Boulder", "Seattle", , "San Francisco"} yes? LIST svar[i=@ngd] *** NOTE: @NGD of string variable, counting null strings as missing VARIABLE : {"Boulder", "Seattle", , "San Francisco"} (# of points) X : 0.5 to 4.5 (number of valid) 3.000 yes? LIST svar[i=@nbd] *** NOTE: @NBD of string variable, counting null strings as missing VARIABLE : {"Boulder", "Seattle", , "San Francisco"} (# of points) X : 0.5 to 4.5 (number flagged bad) 1.000 ! This is the same as, yes? LET svar = {"Boulder", "Seattle", "", "San Francisco"}
7.2.16 Further functions
String versions of some other functions are available. Please see the documentation on each function. These include
XCAT, YCAT, ZCAT, TCAT, Concatenation functions which detect the data type of their argument and work accordingly
XSORT, YSORT, ZSORT, TSORT, which also detect the data type of their arguments. Recall that the SORT commands return the index values of the sorted data.
SAMPLEI, SAMPLEJ, SAMPLEK, SAMPLEL, which also detect the data type of their arguments.
IS_ELEMENT_OF_STR Returns the index value in argument 2 for each string in argument 1
IS_ELEMENT_OF_STR Returns 1 if first argument contains any of the values in 2nd argument