zsh:命令替换、正确的引号和反斜杠(再次)
zsh: command substitution, proper quoting and backslash (again)
(注意:这是我发帖 的后续问题,但现在更复杂了)。
我有一个函数_iwpath_helper,它向标准输出输出一条路径,其中可能包含spaces。为了便于讨论,我们假设 _iwpath_helper 总是 return 是一个常量文本,例如
function _iwpath_helper
{
echo "home/rovf/my directory with spaces"
}
我还有一个函数 quote_stripped 需要一个参数,如果这个参数被引号括起来,它会删除它们并 return 留下剩余的文本。如果参数没有被引号包围,则 return 保持不变。这是它的定义:
function quote_stripped
{
echo ${1//[\"\']/}
}
现在我按以下方式组合这两个函数:
target=$(quote_stripped "${(q)$(_iwpath_helper)}")
(当然,'quote_stripped' 在这个玩具示例中是不必要的,因为 _iwpath_helper 在这里不是 return 引号分隔的路径,但在实际应用程序中,它有时会)。
现在的问题是变量 target 包含一个 real 反斜杠字符,即如果我做一个
echo +++$target+++
明白了
+++home/rovf/my\ directory\ with\ spaces
如果我尝试
cd $target
我的系统出现错误消息,目录
home/rovf/my/ directory/ with/ spaces
不会存在。
(如果您想知道正斜杠的来源:我在 Cygwin 上使用 运行,我猜在这种情况下 cd 命令只是将反斜杠解释为正斜杠,以便更好地适应Windows 环境)。
我猜物理上出现在变量 target 中的反斜杠是由我应用于 $(_iwpath_helper) 的 (q) 扩展标志引起的。我现在的问题是我不能简单地删除 (q),因为没有它,函数 quote_stripped 将仅在参数 $1 上获取字符串的第一部分,直到第一个 space (/home/rovf/my).
我怎样才能正确地写这个?
我认为您只是想避免尝试手动删除引号,并使用 (Q)
扩展标志。比较:
% v="a b c d"
% echo "$v"
a b c d
% echo "${(q)v}"
a\ b\ c\ d
% echo "${(Q)${(q)v}}"
a b c d
chepner 是对的:我试图取消引用字符串的方式很愚蠢(我在 "Bourne Shell way" 中想得太多了),我应该使用 (Q) 标志。
这是我的解决方案:
target="${(Q)$(_iwpath_helper)}"
不再需要 quote_stripped 功能....
(注意:这是我发帖
我有一个函数_iwpath_helper,它向标准输出输出一条路径,其中可能包含spaces。为了便于讨论,我们假设 _iwpath_helper 总是 return 是一个常量文本,例如
function _iwpath_helper
{
echo "home/rovf/my directory with spaces"
}
我还有一个函数 quote_stripped 需要一个参数,如果这个参数被引号括起来,它会删除它们并 return 留下剩余的文本。如果参数没有被引号包围,则 return 保持不变。这是它的定义:
function quote_stripped
{
echo ${1//[\"\']/}
}
现在我按以下方式组合这两个函数:
target=$(quote_stripped "${(q)$(_iwpath_helper)}")
(当然,'quote_stripped' 在这个玩具示例中是不必要的,因为 _iwpath_helper 在这里不是 return 引号分隔的路径,但在实际应用程序中,它有时会)。
现在的问题是变量 target 包含一个 real 反斜杠字符,即如果我做一个
echo +++$target+++
明白了
+++home/rovf/my\ directory\ with\ spaces
如果我尝试
cd $target
我的系统出现错误消息,目录
home/rovf/my/ directory/ with/ spaces
不会存在。
(如果您想知道正斜杠的来源:我在 Cygwin 上使用 运行,我猜在这种情况下 cd 命令只是将反斜杠解释为正斜杠,以便更好地适应Windows 环境)。
我猜物理上出现在变量 target 中的反斜杠是由我应用于 $(_iwpath_helper) 的 (q) 扩展标志引起的。我现在的问题是我不能简单地删除 (q),因为没有它,函数 quote_stripped 将仅在参数 $1 上获取字符串的第一部分,直到第一个 space (/home/rovf/my).
我怎样才能正确地写这个?
我认为您只是想避免尝试手动删除引号,并使用 (Q)
扩展标志。比较:
% v="a b c d"
% echo "$v"
a b c d
% echo "${(q)v}"
a\ b\ c\ d
% echo "${(Q)${(q)v}}"
a b c d
chepner 是对的:我试图取消引用字符串的方式很愚蠢(我在 "Bourne Shell way" 中想得太多了),我应该使用 (Q) 标志。
这是我的解决方案:
target="${(Q)$(_iwpath_helper)}"
不再需要 quote_stripped 功能....