Sorry for the vague subject, I'm not 100% sure how to ask this. Assume I have a plain text file "$HOME/MyReferenceDoc.txt" which has these lines: "$HOME/glue/sticks" "$HOME/foo/bar" "$HOME/work/files" And I want to get the matching line which has '/foo/' MYVAR=$(fgrep '/foo/' "$HOME/MyReferenceDoc.txt") `$MYVAR` will now equal "$HOME/foo/bar" (with literal double-quotes and a literal '$HOME') Let's assume my actual home dir is '/home/james' My question is: How can I tell zsh the it should expand the "$HOME" in "$MYVAR" to "/home/james"? Even if I do: echo "$MYVAR" I get the literal "$HOME" including double-quotes in the output. I guess this must be some foundational Unix thing that I don't understand properly, but all of my attempts to google it have come up short because I'm not sure what to search for other than "expand variable" but it's not quite that either. Thanks Tj
On Fri, May 15, 2020 at 11:48 PM TJ Luoma <luomat@gmail.com> wrote: > > Assume I have a plain text file "$HOME/MyReferenceDoc.txt" which has > these lines: > > "$HOME/glue/sticks" > "$HOME/foo/bar" > "$HOME/work/files" > > And I want to get the matching line which has '/foo/' MYVAR=${(f@M)$(<~/MyReferenceDoc.txt):#*/foo/*} > My question is: How can I tell zsh the it should expand the "$HOME" in > "$MYVAR" to "/home/james"? print -r -- ${(Qe)MYVAR} Or leave out the Q if you want the double-quotes preserved.
> On Fri, May 15, 2020 at 11:48 PM TJ Luoma <luomat@gmail.com> wrote:
>
> Assume I have a plain text file "$HOME/MyReferenceDoc.txt" which has
> these lines:
>
> "$HOME/glue/sticks"
> "$HOME/foo/bar"
> "$HOME/work/files"
What is the meaning of quotes? Are these all equivalent?
"$HOME/foo/bar"
'$HOME/foo/bar'
$HOME/foo/bar
\$HOME/foo/bar
Code posted by Bart assumes that they are. ${(Qe)MYVAR} have the same
value if MYVAR is set to any of these lines.
Roman.
On Sat, May 16, 2020 at 12:14 AM Roman Perepelitsa
<roman.perepelitsa@gmail.com> wrote:
>
> What is the meaning of quotes? Are these all equivalent?
>
> "$HOME/foo/bar"
> '$HOME/foo/bar'
> $HOME/foo/bar
> \$HOME/foo/bar
>
> Code posted by Bart assumes that they are. ${(Qe)MYVAR} have the same
> value if MYVAR is set to any of these lines.
You're correct about Q but only the one with a backslash seems to make
any difference to ${(e)...}:
% print -rl -- $quotings
"$HOME/foo/bar"
'$HOME/foo/bar'
$HOME/foo/bar
\$HOME/foo/bar
$'$HOME/foo/bar'
% print -rl -- ${(e)quotings}
"/Users/schaefer/foo/bar"
'/Users/schaefer/foo/bar'
/Users/schaefer/foo/bar
$HOME/foo/bar
$'/Users/schaefer/foo/bar'
%
Compare this, which is I'm sure what you were thinking of:
% eval print -rl -- $quotings
/Users/schaefer/foo/bar
$HOME/foo/bar
/Users/schaefer/foo/bar
$HOME/foo/bar
$HOME/foo/bar
%
TJ Luoma wrote on Sat, 16 May 2020 02:46 -0400:
> Even if I do:
>
> echo "$MYVAR"
>
> I get the literal "$HOME" including double-quotes in the output.
>
> I guess this must be some foundational Unix thing that I don't
> understand properly, but all of my attempts to google it have come up
> short because I'm not sure what to search for other than "expand
> variable" but it's not quite that either.
Variable values can be any string of bytes. If you can create
a file that contains something, you can set a variable's value to that
something.
When you type «echo "$HOME"» on the command line, HOME is the name of
a variable whose value is «/home/alice». However, it's also possible to
have a variable whose value is literally «"$HOME"» (7 bytes). If you
print that variable's value, you'll get those 7 bytes back verbatim:
.
% s='"$HOME"'
% echo $s
"$HOME"
%
Values don't undergo variable expansion. If they did, stuff like
.
% s='"$s"'
% echo $s
.
would either crash or hang (depending on how precisely it's implemented).
Flags such as ${(e)foo}, ${~foo}, and ${(P)foo} let you specifically ask for
a word to be expanded. Even then, only one level of expansion happens:
.
% s='$foo'
% foo='$bar'
% bar='This is bar'
% print -r -- ${s}
$foo
% print -r -- ${(e)s}
$bar
%
Whether any of these flags is the right tool for the job depends on the context.
Cheers,
Daniel
P.S. «echo $s» does _not_ print $s verbatim for arbitrary values of $s —
for example, backslash escape sequences would be expanded — but that
doesn't matter in this case.
Many thanks. These are ones that I do not remember having come across before, but I'm glad to know them now. - TJ