Subscript Flags

As if subscripting weren't powerful enough already, zsh offers flags that modify the standard behavior for selecting a portion of an array or string.

Syntax

Each flag is one letter. A couple of the flags take arguments; they are of the form F:arg: where F is the one-letter flag and arg is the argument to the flag.

The group of one or more flags you wish to specify must be surrounded immediately by parenthesis. This group can then come immediately after the opening bracket. If a range is specified (2 subscripts separated by a comma), you may put another group of flags immediately after the comma.

${VAR[(X)expr1,(Y)expr2]

where X is a group of flags and Y is a possibly different group of flags.

The various flags


Flag: w

Tells zsh to subscript a scalar (string) by words rather than individual characters.

Example:

  > VAR="this is a big long sentence"
  > echo $VAR[(w)5]
  long
  > echo $VAR[2,(w)4]
  his is a big
  > echo $VAR[(w)2,15]
  is a big l
  > echo $VAR[(w)5,17]
  lon
  > echo $VAR[(w)-3,-4]
  big long sente
  > echo $VAR[(w)-5,(w)-2]
  is a big long
  

Flag: s:string: (Used with w)

If you would like to tokenize (split) a scalar parameter on something besides whitespace, use the s flag.

Example:

  > AR="this/is/a/long/sentence"
  > echo $AR[(ws:/:)4]
  long
  

Flag: p

Sometimes you will need to split on strange or non-printable characters. If you add the p flag before the s:string: flag, you can use all of the print escape sequences (print is a zsh built-in command).

A convoluted example to elaborate...

  > # The < BEEP > marks where the computer beeps
  > AR="this\C-gis a long sentence"
  > echo $AR
  this\C-gis a long sentence
  > print $AR
  this< BEEP >is a long sentence
  > # Don't forget to escape the backslash for the control character!
  > echo $AR[(wps:\\C-g:)1]
  this
  

Flag: f

Use the f flag if you want to subscript a parameter on a per-line basis. This is shorthand for (wps:\n:).

Example:

  > AR=`head /etc/passwd`
  > echo $AR[(f)2]
  sumikeh:x:0:3::/:/usr/bin/zsh
  >
  
Looks like 'sumikeh' has his shell set correctly
Flag: r

This is one of the more interesting and useful subscript flags. When you specify the r flag, zsh treats the subscript expression as a pattern instead of an integer.

What gets returned depends on what type of variable you are subscripting.

If you are subscripting: The r flag returns:
An array The first element that matches the pattern
A scalar The first substring in the variable subscripted that macthes the pattern
A scalar with the w subscript flag The first word that matches pattern


Flag: R

This flag is just like the r flag, but instead, it returns the last matching item according to the table above.


Flag: i

This flag is just like the r flag, but it returns the index of the match.


Flag: I

This flag is just like the i flag, but it returns the index of the last match.


Flag: n:expr:

The n flag is used with one of the r, R, i, or I flags.

expr is an integer. (Or an expression that evaluates to an integer!) Let's call this value X. Zsh will return the Xth match (or Xth to the last match.)