Operators

rsh supports the following operators for common math, logic, and string operations:

Operator Description
+ add
- subtract
* multiply
/ divide
// floor division
mod modulo
** exponentiation (power)
== equal
!= not equal
< less than
<= less than or equal
> greater than
>= greater than or equal
=~ regex match / string contains another
!~ inverse regex match / string does not contain another
in value in list
not-in value not in list
not logical not
and and two Boolean expressions (short-circuits)
or or two Boolean expressions (short-circuits)
xor exclusive or two boolean expressions
bit-or bitwise or
bit-xor bitwise xor
bit-and bitwise and
bit-shl bitwise shift left
bit-shr bitwise shift right
starts-with string starts with
ends-with string ends with
++ append lists

Parentheses can be used for grouping to specify evaluation order or for calling commands and using the results in an expression.

Order of Operations

Operations are evaluated in the following order (from highest precedence to lowest):

  • Parentheses (())
  • Exponentiation/Power (**)
  • Multiply (*), Divide (/), Integer/Floor Division (//), and Modulo (mod)
  • Add (+) and Subtract (-)
  • Bit shifting (bit-shl, bit-shr)
  • Comparison operations (==, !=, <, >, <=, >=), membership tests (in, not-in, starts-with, ends-with), regex matching (=~, !~), and list appending (++)
  • Bitwise and (bit-and)
  • Bitwise xor (bit-xor)
  • Bitwise or (bit-or)
  • Logical and (&&, and)
  • Logical xor (xor)
  • Logical or (||, or)
  • Assignment operations
> 3 * (1 + 2)
9

Types

Not all operations make sense for all data types. If you attempt to perform an operation on non-compatible data types, you will be met with an error message that should explain what went wrong:

> "spam" - 1
Error: rsh::parser::unsupported_operation (link)

  × Types mismatched for operation.
   ╭─[entry #49:1:1]
 1  "spam" - 1
   · ───┬──  
   ·        ╰── int
   ·       ╰── doesn't support these values.
   ·    ╰── string
   ╰────
  help: Change string or int to be the right types and try again.

The rules might sometimes feel a bit strict, but on the other hand there should be less unexpected side effects.

Regular Expression / string-contains Operators

The =~ and !~ operators provide a convenient way to evaluate regular expressionsopen in new window. You don't need to know regular expressions to use them - they're also an easy way to check whether 1 string contains another.

  • string =~ pattern returns true if string contains a match for pattern, and false otherwise.
  • string !~ pattern returns false if string contains a match for pattern, and true otherwise.

For example:

foobarbaz =~ bar # returns true
foobarbaz !~ bar # returns false
ls | where name =~ ^rsh # returns all files whose names start with "rsh"

Both operators use the Rust regex crate's is_match() functionopen in new window.

Case Sensitivity

Operators are usually case-sensitive when operating on strings. There are a few ways to do case-insensitive work instead:

  1. In the regular expression operators, specify the (?i) case-insensitive mode modifier:
"FOO" =~ "foo" # returns false
"FOO" =~ "(?i)foo" # returns true
  1. Use the str contains command's --insensitive flag:
"FOO" | str contains --insensitive "foo"
  1. Convert strings to lowercase with str downcase before comparing:
("FOO" | str downcase) == ("Foo" | str downcase)