## 28.5. String Editing (Colon) Operators

When the C shells, zsh, and bash do history substitutions (Section 30.8) they can also edit the substitution. The C shells and zsh -- but not bash -- can also edit variable substitutions (Section 35.9). (bash has a different syntax, which zsh understands, too.) For instance, in the first example below, when `!$` contains `/a/b/c`, adding the "head" operator `:h` will give just the head of the pathname, `/a/b`.

For a complete but very terse list of these operators, see the csh manual page. We hope the examples below will help you understand these useful operators.

- `:h` gives the head of a pathname (Section 31.2), as follows:

  >     % echo /a/b/c
  >     /a/b/c
  >     % echo !$:h
  >     echo /a/b
  >     /a/b

  That took off the filename and left the header. This also could be used with C shell variables (Section 35.9) as:

  >     % set x = /a/b/c
  >     % echo $x
  >     /a/b/c
  >     % echo $x:h
  >     /a/b

- `:r` returns the root of a filename:

  >     % echo xyz.c abc.c
  >     xyz.c abc.c
  >     % echo !$:r
  >     echo abc
  >     abc

  The `:r` removed the `.c` from the last argument, leaving the root name. This could also be used in C shell variable names:

  >     % set x = abc.c
  >     % echo $x:r

- `:g` makes the operation global if you have more than one name. For example:

  >     % set x = (a.a b.b c.c)
  >     % echo $x:gr
  >     a b c

  The `:gr` operator stripped off all dot (.) suffixes. By the way, this use of `g` does not work with the history commands.

  This is the C shell's answer to the basename (Section 36.13) command.

- `:e` returns the extension (the part of the name after a dot). Using csh variables:

  >     % set x=(abc.c)
  >     % echo $x:e
  >     c

  No luck using that within history, either.

- `:t` gives the tail of a pathname -- the actual filename without the path:

  >     % echo /a/b/c
  >     /a/b/c
  >     % echo !$:t
  >     c

  With csh variables:

  >     % set x=(/a/b/c)
  >     % echo $x:t
  >     c

  And with multiple pathnames, you can do it globally with:

  >     % set x=(/a/b/c /d/e/f /g/h/i)
  >     % echo $x:gt
  >     c f i

  The corresponding heads would be:

  >     % set x=(/a/b/c /d/e/f /g/h/i)
  >     % echo $x:gh

- `:p` prints the command but does not execute it (Section 30.11):

  >     % echo *
  >     fn1 fn2 fn3
  >     % !:p
  >     echo fn1 fn2 fn3

- `:q` prevents further filename expansion or prints the command as is:

  >     % echo *
  >     fn1 fn2 fn3
  >     % !:q
  >     echo *
  >     *

  The first command echoed the files in the directory, and when the `:q` was applied, it echoed only the special character.

- `:x` is like `:q`, but it breaks the line into words. That is, when using `:q`, it is all one word, while `:x` will break it up into multiple words. `:q` and `:x` are more often used with C shell arrays.

[Wait, Dan, what about `&` on the right-hand side to repeat the previous substitution? And there's more since Dan wrote this article (in 1983!). tcsh also has `:u` to convert the first lowercase letter to uppercase and `:l` to convert the first uppercase letter to lowercase. In zsh, `:u` converts all letters to uppercase and `:l` converts all letter to lowercase. zsh also has `f` and `F` to repeat a substitution until it fails -- and even more. Check your shell's manual page. -- JP]

-- DR

Copyright © 2003 O'Reilly & Associates. All rights reserved.