通过Bash引用传递的更新数组 [英] Update array passed by reference with BASH

查看:25
本文介绍了通过Bash引用传递的更新数组的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想编写一个接受数组变量名并更新内容的函数。例如:

ARRAY1=("test 1" "test 2" "test 3")
toUpper ARRAY1

for arg in "${ARRAY1[@]}"; do
  echo "arg=$arg"
done

# output
arg=TEST 1
arg=TEST 2
arg=TEST 3

我尝试过这样做,它需要输入数组的副本。使用间接引用,我能够创建输入变量的副本。数组的副本用于获取元素的计数。如果有更好的方法,请让我知道。

function toUpper() {
  local ARRAY_NAME=$1
  local ARRAY_REF="$ARRAY_NAME[@]"
  # use an indirect reference to copy the array so we can get the count
  declare -a ARRAY=("${!ARRAY_REF}")

  local COUNT=${#ARRAY[@]}

  for ((i=0; i<$COUNT; i++)); do
    local VAL="${ARRAY[$i]}"
    VAL=$(echo $VAL | tr [:lower:] [:upper:])
    echo "ARRAY[$i]="$VAL""
    eval "$ARRAY_NAME[$i]="$VAL""
  done
}

ARRAY1=( "test" "test 1" "test 3" )

toUpper ARRAY1

echo
echo "Printing array contents"
for arg in "${ARRAY1[@]}"; do
  echo "arg=$arg"
done

推荐答案

使用Bash4.3+您可以

arr=( "test" "test 1" "test 3" )
toUpper() { declare -n tmp="$1"; printf "%s
" "${tmp[@]^^}"; }

toUpper arr
TEST
TEST 1
TEST 3

更新:以反映原始数组中的更改:

toUpper() {
   declare -n tmp="$1"; 
   for ((i=0; i<"${#tmp[@]}"; i++)); do
      tmp[i]="${tmp[i]^^}"
    done;
}

arr=( "test" "test 1" "test 3" )
toUpper arr
printf "%s
" "${arr[@]}"
TEST
TEST 1
TEST 3

更新2:这里有一种方法可以使它在旧Bash(4之前)版本中运行,而不需要eval

upper() {
   len=$2
   for ((i=0; i<len; i++)); do
      elem="${1}[$i]"
      val=$(tr '[:lower:]' '[:upper:]' <<< "${!elem}")
      IFS= read -d '' -r "${1}[$i]" < <(printf '%s' "$val")
   done;
}

arr=( "test" "test 1" "test 3" )
upper arr ${#arr[@]}
printf "%s
" "${arr[@]}"
TEST
TEST 1
TEST 3

这篇关于通过Bash引用传递的更新数组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆