bash - 我可以使用与 bash 和 zsh 相同的语法循环遍历关联数组的键吗

标签 bash shell zsh oh-my-zsh

我想循环关联数组的键,但我希望我的脚本能够在 zsh 和 bash 中工作。有没有一种方法(语法)可以在两者中工作

这个我知道

zsh:

for k in "${(k)array[@]}" do echo $k; done

bash :

for k in "${!array[@]}" do echo $k; done

顺便说一句。我实际上使用 oh-my-zsh,所以我不能真正使用某些东西作为模拟 ksh,因为它会使我的终端崩溃。

最佳答案

您可以将每个实现包装在一个函数中,并仅定义适合当前 shell 的函数:

if [[ $ZSH_VERSION ]]; then
  keys_for_array() {
    local array=$1 dest=$2
    [[ $1 && $2 ]] || { echo "Usage: keys_for_array source-array dest-array" >&2; return 1; }
    : ${(AP)dest::=${(kP)array}}
  }
elif [[ $BASH_VERSION && ! $BASH_VERSION =~ ^([123][.]|4[.][012]) ]]; then
  keys_for_array() {
    [[ $1 && $2 ]] || { echo "Usage: keys_for_array source-array dest-array" >&2; return 1; }
    local -n array=$1 dest=$2
    eval 'dest=( "${!array[@]}" )'
  }
else
  keys_for_array() { echo "ERROR: keys_for_array not available for this shell" >&2; return 1; }
fi

[[ $ZSH_VERSION ]] && typeset -A aa=( 1 one 2 two )
[[ $BASH_VERSION ]] && declare -A aa=( [1]=one [2]=two )
keys_for_array aa aak

declare -p aak

...在 bash 上运行时,输出为:

declare -a aak=([0]="1" [1]="2")

...在 zsh 上运行时,输出为:

typeset -a aak=( 1 2 )

无论哪种情况,您都可以迭代它们:

keys_for_array aa aak
for key in "${aak[@]}"; do
  echo "Key $key has value ${aa[$key]}"
done

请注意,上面的两个函数在语法上在两个 shell 中都是有效的。否则,可能需要使用 evalsource 仅有条件地引入它们。就我个人而言,我会使用可移植性库的 bash 和 zsh 版本创建两个单独的文件,并仅获取适合当前 shell 的文件。

关于bash - 我可以使用与 bash 和 zsh 相同的语法循环遍历关联数组的键吗,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51445550/

相关文章:

linux - 通过 bash 脚本从文本文件运行命令

Java ProcessBuilder 无法运行简单的脚本

linux - 无法在树莓派 (raspbian) 上执行简单的 bash 脚本

linux - 使用 git 将项目分层

zsh - 如何在 zsh 提示符中将文本设置为斜体?

bash - 如何捕获后台进程的输出

shell - 查找并删除主文件夹中的所有符号链接(symbolic link),使其无法正常工作

linux - 如何知道linux中的执行时间

shell - 在shell脚本中打印文件时间

python - 使用Python打开shell环境,运行命令退出环境