Next Previous Up Contents
Next: Functions
Up: Algebraic Expression Syntax
Previous: Operators

### 10.6 Strings and Quoting

Sometimes in an algebraic expression you will want to use a literal string value, for instance if you want to test a string-valued column for equality with some fixed string. Literal strings must always be delimited by double quote characters (`"`). This can be problematic, since (single or double) quote characters are interpreted within STILTS parameter values as grouping text that may contain spaces into a single token. And, depending how you are invoking STILTS, the shell may do a similar thing: interpret (single or double) quote characters on the command line as grouping text that may contain spaces or shell magic characters into a single string (such as a parameter value assignment) to pass to STILTS. To complicate matters further, literals of the `char` type (single characters) in the expression language are delimited using single-quote characters (`'`), though it's not very often necessary to deal with `char` values in STILTS. And in a few cases specific parameters might have their own requirements for quotes (like the `adql` parameter of `tapquery`; in ADQL string literals need single quotes and double quotes delimit identifiers).

To summarise the common uses of quotes that you might have to make:

- Delimit a literal string in the expression language: double quote (`"`)
- Delimit a space-containing string (e.g. a list of tokens) that forms part of a STILTS parameter value assignment: single or double quote (`'` or `"`)
- Protect a STILTS parameter value assignment from the Unix shell (avoid breaking into multiple words, ignore magic characters): single or double quote (`'` or `"`)

The last one only applies if you are running STILTS via a Unix-like shell; similar considerations will apply from different OSs like MS Windows, but if you are running JyStilts or using the expression language directly e.g. from a GUI application like TOPCAT, this one doesn't apply.

Unfortunately, all this can lead to a kind of quoting hell when trying to write STILTS commands, especially if they have to contain String literals, for which the author apologises :-(. Working round these requirements can be quite messy, but here are some tips:

- String literals in the expression language must always be delimited with double quotes.
- STILTS parameter values sometimes contain spaces or other characters that have meaning for the shell, so it's often a good idea to quote them; `ofmt=votable(format=BINARY)` will fail because the shell tries to interpret the parenthesis characters, but `ofmt='votable(format=BINARY)'`, or `'ofmt=votable(format=BINARY)'`, will succeed.
- If you can avoid spaces in arguments, you won't need so much quoting, so you can write e.g. `cmd='select rmag<12'` instead of `cmd='select "rmag < 12"'`.
- You can use different types of quote for different purposes, e.g. `cmd='keepcols "id ra dec"'` or `cmd="keepcols 'id ra dec'"`. Note however that different types of quote have somewhat different meanings to the shell (single quotes are generally safer).
- In a STILTS parameter value, as well in shell arguments, quotes can be escaped with a preceding backslash (`\`) to prevent them being interpreted as grouping constructs. So although `cmd='select equals(release,"DR4")'` fails (STILTS interprets the double quotes as grouping characters rather than string literal delimiters), `cmd='select equals(release,\"DR4\")'` succeeds.
- In a STILTS parameter value, as well as in shell arguments, spaces can be escaped with a preceding backslash (`\`) to prevent them being interpreted as token separators. So `cmd='keepcols id\ ra\ dec'` can be used to mean the same as `cmd='keepcols "id ra dec"'`.

Armed with this information it is usually possible to phrase a STILTS command on the command line that does what you want. In cases where that seems to be untrue or too painful, there are a couple of ways to avoid use of the shell, removing one layer of quote (mis)interpretation:

- Filter (`cmd`-like) parameters can be specified using file indirection; `cmd=@filename` reads the filter value(s) from the line(s) of the named file
- JyStilts allows you to use python syntax to construct arguments to pass to STILTS without interference from the shell

The comments above concerning the Unix shell are in principle dependent on which shell is in use, but they should apply to `sh`, `bash` and `csh` on any common Unix-like OS including MacOS. Something similar probably applies to other OSes like MS Windows, but the details may be different.

Next Previous Up Contents
Next: Functions
Up: Algebraic Expression Syntax
Previous: Operators

STILTS - Starlink Tables Infrastructure Library Tool Set
Starlink User Note256
STILTS web page: http://www.starlink.ac.uk/stilts/
Author email: m.b.taylor@bristol.ac.uk
Mailing list: topcat-user@jiscmail.ac.uk