Help needed with conditional statement for alias in csh

Dan Bernstein brnstnd at kramden.acf.nyu.edu
Wed Sep 19 12:13:03 AEST 1990


In article <1990Sep18.223605.29379 at eua.ericsson.se> per at erix.ericsson.se (Per Hedeland) writes:
> sh -c 'if test -s /usr/spool/mail/miller; then echo ""; echo "New mail"; echo ""; fi'
> However, turning this into an alias with csh's idea of quoting is awkward if
> at all possible,

Don't give up! If it's not intuitively obvious to you that

  alias mailtest 'sh -c '\''if test -s /usr/spool/mail/miller; then echo ""; echo "New mail"; echo ""; fi'\'

has the right effect, simply use the makealias and quote aliases
presented below.

---Dan


1. How do I quote a string in csh?
2. How do I double-quote a string in csh?
3. How do I make an alias?
4. How do I get the value of a variable into a command?
5. How do I use a string variable in a sed command?


1. How do I quote a string in csh?

Use the quote alias:

  alias a alias
  a quote "/bin/sed 's/\\!/\\\\\!/g' | /bin/sed 's/'\\\''/'\\\'\\\\\\\'\\\''/g'
	   | /bin/sed 's/^/'\''/' | /bin/sed 's/"\$"/'\''/'"

Make sure the alias is all on one line. All quote does is replace ! by \!,
replace ' by '\'', and place single quotes at the beginning and end of the
text. For example,

  % quote
  BEGIN { printf "'" }     (you type this, followed by control-D)
  'BEGIN { printf "'\''" } '     (this is the correctly quoted version)

quote's output will also work under sh.


2. How do I double-quote a string in csh?

The only interpretation inside a single-quoted string is ! and \!. A
double-quoted string allows (in fact, forces) $ and ` interpretation
as well. Here's the dquote alias:

  a dquote "/bin/sed 's/\\!/\\\\\!/g' | /bin/sed 's/"\""/"\""\\"\"\""/g'
	    | /bin/sed 's/^/"\""/' | /bin/sed 's/"\$"/"\""/'"

If you want to prevent interpretation of a $ inside the double-quoted
string, replace it by "\$"; similarly for `. Of course, it may be
simpler in this case to just use single-quoting and replace $foo by
'"$foo"' when you do want it interpreted.


3. How do I make an alias?

Say you've just typed an amazing command that you want to save as an
alias. Use makealias:

  a makealias "quote | /bin/sed 's/^/alias \!:1 /' \!:2*"

For example,

  % foobie 'bletch b' oing     (wow, amazing!)
  % makealias fb
  foobie 'bletch b' oing     (you retype the command, followed by control-D)
  alias fb 'foobie '\''bletch b'\'' oing'

Redirect makealias's output to a file (makealias foo > /tmp/test) and
later copy it to .login, or redirect directly to .login (makealias foo
>> /tmp/.login). (Use .cshrc if you want your aliases in subshells.)

If you want an alias to take arguments, replace a fixed string in the
alias definition by \!:1 (first argument), \!:2* (second argument
through end), etc. There are many more ! substitutions listed in the
csh manual.


4. How do I get the value of a variable into a command?

The shells have set but not show. Here's several ways to print the value
of a variable, $ans, on stdout. ``Working echo'' means one whose worst
vice is a -n option meaning suppress newlines; if your echo interprets
escape sequences, it doesn't qualify. ``Amazing echo'' means one that
doesn't interpret its arguments at all.

sh, with printenv: export ans; printenv ans
sh, with a working echo: (echo -n "$ans"; echo '')
sh, with an amazing echo: echo "$ans"
csh, with a working /bin/echo: (/bin/echo -n "$ans"; /bin/echo '')
csh, with an amazing /bin/echo: /bin/echo "$ans"
csh, with a working builtin echo: echo "$ans"
     NOTE: csh parses builtins strangely, so this works even if ans is "-n...".
sh, on any machine: sed "+$ans" 2>&1 | sed 's/^Unrecognized command: +//'
     CAVEAT: Does not work if $ans contains newlines.
csh, on any machine: sed "+$ans" |& sed 's/^Unrecognized command: +//'
     ANTI-CAVEAT: Because csh is csh, this one works if $ans contains newlines.

The last two hacks are a useful trick to get that variable into the
output stream, which is difficult if both echo and printenv are screwed.
+ can be any character upon which sed chokes. Other similar replacements
include using ls imaginatively and then stripping off the `file not found',
etc.


5. How do I use a string variable in a sed command?

Say you want to replace all occurrences of the string $ans by XXX.
sed "s/$ans/XXX/g" won't work if $ans contains interesting characters.
You have to munge $ans into $pattern so that sed "s/$pattern/XXX/g"
will act as if it had a literal $ans in the first position.

Under sh with printenv,

  export ans ; pattern="`printenv ans | sed 's-\([\.\*\[\\\^\$\/]\)-\\\\\1-g'`"

will do the job. In other cases, rewrite this along the lines of #4 above.
For example, under csh with a working builtin echo, try

  alias literal 'sed '\''s-\([\.\*\[\\\^\$\/]\)-\\\1-g'\'
  alias show 'echo "$\!:1"'

The acid test, of course, is

  show ans | sed "s/`show ans | literal`/XXX/g"

which, no matter what $ans is, will output XXX.


---Dan



More information about the Comp.unix.shell mailing list