Note that in the process of having all these great interactive features added, the c-shell became much less well suited to shell programming than its older but more spry aunt, sh(1).
To find out exactly why you shouldn't write programs in
csh(1), check out Tom Christiansen's rant:
% date Mon Nov 25 13:52:36 PST 1996 % !! date Mon Nov 25 13:52:52 PST 1996
Note that when you use any history retrieval, the resulting command is echoed to stdout before execution so you can see what you've done.
"!!" is available even if you have history disabled. To see if history is enabled, look at the "history" shell variable:
% echo $history history: Undefined variable. % set history=100 % echo $history 100
The number stored in the "history" variable indicates how many commands will be saved for retrieval. To see what commands can be retrieved, use the "history" csh built-in command (see csh_builtins(1)):
% history 41 cd /vobs/Rm/ApeCpt/cpt 42 vi cpt.c 43 clearmake 44 pushd ../.. 45 clearmake lo 46 pushd 47 ls 48 cleartool edcs 49 cleartool ls cpt.c 50 history
There are a number of ways of retrieving commands and parts of commands.
You can redo a specific command from the history list by specifying its number:
% !47 ls
You can specify a number relative to the current command:
% !-2 cleartool ls cpt.c
"!-2" is the only one I ever use since it's the command before the last command, and my mental stack doesn't go any farther than that. "!-1" is equivalent to "!!", so it's not very useful.
You can redo the last command which started with a given string by prefixing that string with a "!":
% !vi vi cpt.c
You need only specify enough characters to make the command unique, so "!v" would have been sufficient there.
You can redo the last command which contained a given string:
% !?edcs cleartool edcs
% ls /vobs/Rm [list of files] % !!/bldtools ls /vobs/Rm/bldtools [different list of files]
If all you want to retrieve is a part of a command, there are a number of modifiers to select specific parts of a retrieved command line. They can be added on to all the methods above.
The command line is regarded as a first word followed by a number of arguments. To get the first word, append ":0"
% !cl:0 catcs cleartool catcs
That retrieved the last command starting with "cl" which was "cleartool ls cpt.c", grabbed just the first word, "cleartool", and then added on "catcs" to that.
Grabbing the first word is seldom very useful since any frequently accessed command is likely to have been aliased to something which takes less characters than the history command to retrieve it, but arguments are a different matter.
To retrieve the first argument to a recalled command, append ":^" The caret should be easy to remember if you know a little about regular expressions since it is the character that matches the beginning of a line.
% cleartool man !cl:^ cleartool man ls
That starts off with "cleartool man", then adds on the first argument to the last command which started with "cl" which was "cleartool ls cpt.c"
To retrieve the last argument to a recalled command, append ":$" The dollar sign should be easy to remember if you know a little about regular expressions since it is the character that matches the end of a line.
% wc !v:$ wc cpt.c
That starts off with "wc", then appends the last argument from the most recent command starting with "v" which in this case was "vi cpt.c"
Retrieving the last argument to the previous command is a very common operation which is further abbreviated "!$" (similarly (though not as usefully) for "!^"):
% mkdir foo % chmod 755 !$ chmod 755 foo % cp *.c !$ cp *.c foo % cd !$ cd foo
Which doesn't save all that much typing if the directory is "foo", but if it's "HcFeDiscombobulateSupportRoutines", then you're a happy camper.
To retrieve the nth argument, just append ":n", so ":1" is equivalent to ":^", ":2" is the second argument, and so on.
To retrieve all the arguments from the retrieved command, append ":*" (For the case of "!!:*", you can abbreviate to "!*")
% cd ls cpt.c cd: Too many arguments. % ct !* ct ls cpt.c
So there I messed up and typed "cd" instead of "ct", so I just typed it again correctly and grabbed the arguments from last time.
There are modifiers to grab ranges of arguments from the previous command, but this tiny techie tip is getting pretty big, so I'll leave it to the interested readers to look up the relevant details in the csh(1) page. csh(1) is, after all, a command you use every day, so it might be time well spent to read about its features.
There are two forms of substitution:
There's a special case for making a change to the previous command since this is something that is often useful. Use carets to show the old string and the new string:
% ls foopar foopar not found % ^foopar^foobar^ ls foobar
You can leave off the trailing caret. Note that this substitution is not global, i.e., it only changes the first occurrence of the first string ("^o^x" would only change "foopar" into "fxopar", not "fxxpar"). Also note that the caret substitution isn't very forgiving of whitespace in its patterns, and will say "Modifier failed." at its first sign of confusion. At which point, you'll have to resort to the general substitution method since the prior command is now your failed caret substitution, not the command you're trying to modify.
Also note that substitution is not subject to expansion of shell meta-characters, so you can substitute *s and things without strange things happening.
General substitution is done with the ":s" operator: ":s/old/new/".
"!!:s/foo/bar/" is equivalent to "^foo^bar^" in all respects: the trailing delimiter can be omitted, the second pattern can be ommitted to delete the first pattern, white space is not well tolerated.
However, the ":s//" method is more flexible since it can be used with any retrieved command whereas the caret substitution only works with the previous command.
The ":s//" substitution can also be extended to replace all occurrences of the string by prefacing the "s" with a "g" as in the following:
% mv foo.c foo.cc % !!:gs/foo/bar mv bar.c bar.cc
Up to the TTTT index
Tuesday Tiny Techie Tips are all © Copyright 1996-1997 by Jeff Youngstrom. Please ask permission before reproducing any of this material.