Path: utzoo!utgpu!news-server.csri.toronto.edu!cs.utexas.edu!yale!cmcl2!kramden.acf.nyu.edu!brnstnd From: brnstnd@kramden.acf.nyu.edu (Dan Bernstein) Newsgroups: comp.unix.shell Subject: Re: Help needed with conditional statement for alias in csh Message-ID: <1461:Sep1902:13:0390@kramden.acf.nyu.edu> Date: 19 Sep 90 02:13:03 GMT References: <6932.26ed237f@uwovax.uwo.ca> <26553@mimsy.umd.edu> <1990Sep18.223605.29379@eua.ericsson.se> Organization: IR Lines: 132 In article <1990Sep18.223605.29379@eua.ericsson.se> per@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