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]
Copyright © 2003 O'Reilly & Associates. All rights reserved.