0

配列変数名を取り、内容を更新する関数を書きたいと思います。例えば:

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
4

2 に答える 2

5

あなたができるBASH 4.3+を使用して

arr=( "test" "test 1" "test 3" )
toUpper() { declare -n tmp="$1"; printf "%s\n" "${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\n" "${arr[@]}"
TEST
TEST 1
TEST 3

Update2:これは、古い 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\0' "$val")
   done;
}

arr=( "test" "test 1" "test 3" )
upper arr ${#arr[@]}
printf "%s\n" "${arr[@]}"
TEST
TEST 1
TEST 3
于 2015-04-06T14:43:06.263 に答える
1

anubhava の回答は、bash 4.3 以降に最適です。bash 3 をサポートするには、namevar の使用を置き換え、大文字の展開を置き換えるためにeval(非常に慎重に、 で生成された文字列を使用して) を使用できます。printf %qtr${foo^^}

toUpper() {
  declare -a indexes
  local cmd idx item result
  printf -v cmd 'indexes=( "${!%q[@]}" )' "$1"; eval "$cmd"
  for idx in "${indexes[@]}"; do
     printf -v cmd 'item=${%q[%q]}' "$1" "$idx"; eval "$cmd"
     result=$(tr '[:lower:]' '[:upper:]' <<<"$item")
     printf -v cmd '%q[%q]=%q' "$1" "$idx" "$result"; eval "$cmd"
  done
}
于 2015-04-06T17:17:56.370 に答える