Regular Expression delimiters
Dan Bernstein
bernsten at phoenix.Princeton.EDU
Thu Apr 13 07:19:58 AEST 1989
So far, nobody has given an answer to this question that handles more
than a few special cases. Now Chris Torek gives up completely.
Here are some solutions, all thoroughly tested, from the devious mind
that brought you the aliases `quote' and `makealias'. Each example
munges $ans into $pattern, so that sed "s/$pattern/whatever/g" acts
as if it had a literal $ans in the first position.
sh, if you have printenv:
export ans ; pattern="`printenv ans | sed 's-\([\.\*\[\\\^\$\/]\)-\\\\\1-g'`"
sh, if you have a working echo (whose only caveat is -n):
pattern="`(echo -n \"$ans\";echo '') | sed 's-\([\.\*\[\\\^\$\/]\)-\\\\\1-g'`"
NOTE: Chris, want to take back that ``no workaround''?
csh, if you have a working /bin/echo (whose only caveat is -n):
set pattern="`(echo -n "\"\$ans\"";echo '')
| sed 's-\([\.\*\[\\\^\"\$"\/]\)-\\\1-g'`"
csh, if you have a working builtin echo (whose only caveat is -n):
set pattern="`echo "\"\$ans\"" | sed 's-\([\.\*\[\\\^\"\$"\/]\)-\\\1-g'`"
NOTE: csh parses builtins strangely, so this works even if ans is "-n ...".
sh, on any machine (put it all on one line):
pattern="`sed \"$ans\" 2>&1 | sed 's/^Unrecognized command: //'
| sed 's-\([\.\*\[\\\^\$\/]\)-\\\\\1-g'`"
CAVEAT: Does not work if $ans contains newlines.
csh, on any machine (put it all on one line):
set pattern="`sed "\"\$ans\"" |& sed 's/^Unrecognized command: //'
| sed 's-\([\.\*\[\\\^\$\/]\)-\\\1-g'`"
ANTI-CAVEAT: Because csh is csh, this one works if $ans contains newlines.
Some notes about the last two: The sequence ^A (appearing twice in
each---but not the ^U) can be any (identical) string upon which sed
will choke; I use the control character. The general idea of
sed "^A$ans" 2>&1 | sed 's/^Unrecognized command: ^A//'
is to somehow manage to get that environment variable into the
input-output stream, which is difficult if both echo and printenv
are screwed. Other similar replacements include using ls imaginatively
and then stripping off the `file not found', etc.
It wouldn't take much work to make a `literal' alias, by feeding the
above ideas through `makealias', so that all you'd have to do for this
problem is type
sed "s/`literal ans`/whatever/g"
Those who have seen my csh aliases `quote' and `makealias' know both
that I have a masochistic enjoyment of these problems and that my
solutions work. So unless I've screwed up, let's cut the discussion.
---Dan Bernstein, bernsten at phoenix.princeton.edu
More information about the Comp.unix.questions
mailing list