Zsh 相当于 bash 的什么
expr index "abcdefghijklmnopqrstuvwxyz" xyzd
我正在尝试查找子字符串的索引。
答案1
如果您正在寻找zsh
非标准expr
用法的内置替代方案(与顺便说一句无关bash
),您可以这样做:
$ a=abcdefghijklmnopqrstuvwxyz b=xyzd
$ echo ${a[(i)[$b]]}
4
使用i
,您可以获得的索引第一的匹配(如果没有匹配,则加上干草堆的长度)。相反I
,您将获得最后一个匹配项(如果没有匹配项,则为 0)。
使用任何类似 POSIX 的 shell(包括bash
和zsh
)
$ s=${a%%[$b]*}
$ echo "$(($#s + 1))"
4
答案2
GNU coreutils 包中的实现expr
是一个外部实用程序,无论您使用什么 shell,都可以以相同的方式使用。
在zsh
,
expr index "abcdefghijklmnopqrstuvwxyz" xyzd
将返回4
,就像在 shellbash
或任何其他 shell 中一样。
index
GNU 中的操作是expr
对标准expr
,这意味着您可能会在expr: syntax error
没有特定实现的系统上遇到错误expr
。这与您使用什么 shell 无关。
答案3
expr index "abcdefghijklmnopqrstuvwxyz" xyzd
我正在尝试查找子字符串的索引。
子字符串的索引,还是字符的索引?expr index
查找第二组中给出的任何字符,即上面查找第一个字符的位置d
,而不是子字符串xyzd
(字符串中不存在)。
要查找子字符串的位置,您可以在标准 shell 中执行以下操作:
haystack=abcdefghijklmnopqrstuvwxyz
needle=jkl
x=${haystack%%$needle*};
现在x
包含该子字符串之前的字符串部分,( ,在本例中)"${#x}"
的从零开始的位置也是如此。jkl
9
要从一组字符中查找字符(字节)的位置,您可以类似地使用:
haystack=abcdefghijklmnopqrstuvwxyz
needle=xqe;
x=${haystack%%[$needle]*};
这里,"${#x}"
是 4。这两种方法的缺点是,如果未找到所搜索的字符串/字符,则x
包含整个haystack
,因此您需要"${#x}"
与整个长度haystack
(非零)进行比较以查看是否找到匹配项:
haystack=abcdefghijklmnopqrstuvwxyz
needle=qqq
x=${haystack%%$needle*}
if [ "${#x}" = "${#haystack}" ]; then echo "$needle not found"; fi
答案4
正如 Kusalananda 在他的评论中已经指出的那样,你当然expr
也可以在 zsh 中使用,但我猜你的意思是 Zsh 是否有内置方法来做到这一点。
答案是“不”,但它包含类似的内容:
v="abcdefghijklmnopqrstuvwxyz"
i=${(SB)v#cdef}
这将设置i
为 3。但是,有两个原因导致其工作方式与expr index
:
在您给出的示例中,您正在搜索XYZD,它不存在于您的字符串中,但由于您的字符串以XYZ,expr
优雅地删除“d”并返回匹配项。有人可能会说 Zsh 的行为在这方面更合理,但当然,如果这对你来说是一个重要问题,我会坚持使用 Zsh。
Zsh 不同的另一个原因是,${(SB)v#...}
如果字符串不存在,则返回 1不是匹配。例如,
echo ${(SB)v#a}
echo ${(SB)v#7}
都会返回 1。仅凭这一点,您无法区分第一个字符的不匹配和匹配。一种可能的解决方案是让它计算比赛的位置和长度:
# N returns the length of the match
index_and_length=${(SBN)v#...}
# index_and_length contains the index, a space, and the length
if [[ ${index_and_length#* } == 0 ]]
then
echo no match
else
index=${index_and_length% *}
echo match at index $index
fi
UDPATE:正如这篇文章的评论所揭示的那样,我误解了expr index
;因此,我的回答是不充分的。但是我们可以调整它,因为要搜索的“字符串”是一个全局模式。因此,方括号可以完成这项工作:
# Search for the first occurance of one of the letters x y z d
index_and_length=${(SBN)v#[xyzd]}