Adr*_*ire 4 shell bash zsh string
我正在寻找:一种在 bash 和 zsh 之间以兼容的方式按字符拆分字符串(变量)的方法。
从不同的来源,我发现了以下命令:
str="part1=part2=part3"
parts=(${(@s:=:)str})
echo ${#parts[@]}
Run Code Online (Sandbox Code Playgroud)
但是,我找不到:相同序列的逃生方法
parts=(${(@s:::)str}) #Not working
parts=(${(@s:\::)str}) #Not working
Run Code Online (Sandbox Code Playgroud)
对于 bash,我发现了这个:
parts=(${str//:/ })
Run Code Online (Sandbox Code Playgroud)
哪个有效,但并不真正兼容。我可以使用以下行来区分外壳:
if [ -z "$(ps -p $$| grep zsh)" ]; then
echo "This is bash (Use bash solution here)"
else
echo "This is zsh (Use Zsh solution here)"
fi
Run Code Online (Sandbox Code Playgroud)
但也许一些替代解决方案是兼容的?任何有效的解决方案已经是一个胜利。
Sté*_*las 12
在:有任意字符:
您可以使用:
parts=(${(s/:/)str})
Run Code Online (Sandbox Code Playgroud)
还支持一些常见的字符对,例如:
parts=(${(s[:])str})
Run Code Online (Sandbox Code Playgroud)
如果要使用@标志来保留空元素,则需要引用:
parts=("${(@s[:])str}")
Run Code Online (Sandbox Code Playgroud)
否则@没有区别。
如果是工艺变量,例如$PATH/ $LD_LIBRARY_PATH...又见typeset -T其绑一个数组变量一个标量变量:
$ typeset -T str str_array
$ str='a::b'
$ typeset -p str
typeset -T str str_array=( a '' b )
Run Code Online (Sandbox Code Playgroud)
zsh确实领带$path到$PATH默认(如在csh/ tcsh)。
bash的
parts=(${str//:/ })
Run Code Online (Sandbox Code Playgroud)
是错误的,因为它在替换:为 SPC后应用了 split+glob 。
你会想要:
IFS=: # split on : instead of default SPC TAB NL
set -o noglob # disable glob
parts=( $str"" ) # split+glob (leave expansion unquoted), preserve trailing
# empty part.
Run Code Online (Sandbox Code Playgroud)
zsh如果它处于sh或ksh仿真模式,该代码也可以在. 如果您的目标是编写bash与 和兼容的代码zsh,您可能希望使用 ksh 语法编写它,并确保在解释它时将其zsh置于ksh仿真中(可能仅在某些函数的本地)。
要测试 shell 是否为bash或zsh,您需要测试$BASH_VERSION/$BASH_VERSINFO或$ZSH_VERSION变量是否存在。
split() { # args: string delimiter result_var
if
[ -n "$ZSH_VERSION" ] &&
autoload is-at-least &&
is-at-least 5.0.8 # for ps:$var:
then
eval $3'=("${(@ps:$2:)1}")'
elif
[ "$BASH_VERSINFO" -gt 4 ] || {
[ "$BASH_VERSINFO" -eq 4 ] && [ "${BASH_VERSINFO[1]}" -ge 4 ]
# 4.4+ required for "local -"
}
then
local - IFS="$2"
set -o noglob
eval "$3"'=( $1"" )'
else
echo >&2 "Your shell is not supported"
exit 1
fi
}
split "$str" : parts
Run Code Online (Sandbox Code Playgroud)