4.30. How do I read environment variables with sed?
4.30.1. - on Unix platforms
In Unix, environment variables begin with a dollar sign, such as
$TERM, $PATH, $var or $i. In sed, the dollar sign is used to
indicate the last line of the input file, the end of a line (in the
LHS), or a literal symbol (in the RHS). Sed cannot access variables
directly, so one must pay attention to shell quoting requirements
to expand the variables properly.
To ALLOW the Unix shell to interpret the dollar sign, put the
script in double quotes:
sed "s/_terminal-type_/$TERM/g" input.file >output.file
To PREVENT the Unix shell from interpreting the dollar sign as a
shell variable, put the script in single quotes:
sed 's/.$//' infile >outfile
To use BOTH Unix $environment_vars and sed /end-of-line$/ pattern
matching, there are two solutions. (1) The easiest is to enclose
the script in "double quotes" so the shell can see the $variables,
and to prefix the sed metacharacter ($) with a backslash. Thus, in
sed "s/$user\$/root/" file
the shell interpolates $user and sed interprets \$ as the symbol
for end-of-line.
(2) Another method--somewhat less readable--is to concatenate the
script with 'single quotes' where the $ should not be interpolated
and "double quotes" where variable interpolation should occur. To
demonstrate using the preceding script:
sed "s/$user"'$/root/' file
Solution #1 seems easier to remember. In either case, we search for
the user's name (stored in a variable called $user) when it occurs
at the end of the line ($), and substitute the word "root" in all
matches.
For longer shell scripts, it is sometimes useful to begin with
single quote marks ('), close them upon encountering the variable,
enclose the variable name in double quotes ("), and resume with
single quotes, closing them at the end of the sed script. Example:
#! /bin/sh
# sed script to illustrate 'quote'"matching"'usage'
FROM='abcdefgh'
TO='ABCDEFGH'
sed -e '
y/'"$FROM"'/'"$TO"'/; # note the quote pairing
# some more commands go here . . .
# last line is a single quote mark
'
Thus, each variable named $FROM is replaced by $TO, and the single
quotes are used to glue the multiple lines together in the script.
(See also section 4.10, "How do I handle shell quoting in sed?")
4.30.2. - on MS-DOS and 4DOS platforms
Under 4DOS and MS-DOS version 7.0 (Win95) or 7.10 (Win95 OSR2),
environment variables can be accessed from the command prompt.
Under MS-DOS v6.22 and below, environment variables can only be
accessed from within batch files. Environment variables should be
enclosed between percent signs and are case-insensitive; i.e.,
%USER% or %user% will display the USER variable. To generate a true
percent sign, just enter it twice.
DOS versions of sed require that sed scripts be enclosed by double
quote marks "..." (not single quotes!) if the script contains
embedded tabs, spaces, redirection arrows or the vertical bar. In
fact, if the input for sed comes from piping, a sed script should
not contain a vertical bar, even if it is protected by double
quotes (this seems to be bug in the normal MS-DOS syntax). Thus,
echo blurk | sed "s/^/ |foo /" # will cause an error
sed "s/^/ |foo /" blurk.txt # will work as expected
Using DOS environment variables which contain DOS path statements
(such as a TMP variable set to "C:\TEMP") within sed scripts is
discouraged because sed will interpret the backslash '\' as a
metacharacter to "quote" the next character, not as a normal
symbol. Thus,
sed "s/^/%TMP% /" somefile.txt
will not prefix each line with (say) "C:\TEMP ", but will prefix
each line with "C:TEMP "; sed will discard the backslash, which is
probably not what you want. Other variables such as %PATH% and
%COMSPEC% will also lose the backslash within sed scripts.
Environment variables which do not use backslashes are usually
workable. Thus, all the following should work without difficulty,
if they are invoked from within DOS batch files:
sed "s/=username=/%USER%/g" somefile.txt
echo %FILENAME% | sed "s/\.TXT/.BAK/"
grep -Ei "%string%" somefile.txt | sed "s/^/ /"
while from either the DOS prompt or from within a batch file,
sed "s/%%/ percent/g" input.fil >output.fil
will replace each percent symbol in a file with " percent" (adding
the leading space for readability).