2008/06/20

在 Bash 中使用 Array

本文大約翻譯自這裡,一般人若習慣傳統 xSH 的話,那可能不會想要使用陣列。

Bash 提供一個方便的陣列表示法,雖然在使用上不像 Perl, Python, PHP, 甚至 C/C++, Java, JavaScript 等那麼自然,但是當您會使用陣列時,一些困擾也自然解決。

先來看看表示法:
arr=(Hello World)

主要特點是用小括號,元素間用空白(不限個數)隔開即可。若要個別指定值的話,也很直覺如下:

arr[0]=Hello
arr[1]=World


與別的語言相對上較不直覺得地方在於引用時的語法,底下的範例中大括號是必要的,雖然這在 shell Script 中很常見,但是整個寫起來還是有那麼一點不順眼,習慣就好了:

echo ${arr[0]} ${arr[1]}


底下看一些比較特別的用法,摘要說明在後面註解裡:

$ arr=(hello world) # 初始化陣列,示範與空白數無關
$ arr[5]=. # 讓陣列不連續
$ echo ${arr[*]} # 引用陣列中所有元素
hello world .
$ echo ${!arr[*]} # 引用陣列的所有索引值,因為個別指定時有可能讓陣列跳過某些元素
0 1 5
$ echo ${#arr[*]} # 取得元素個數
3
$ echo ${#arr[0]} # 取得某元素的長度
5


底下用一個完整的範例來說明陣列用法:

#!/bin/bash

array=(one two three four [5]=five) # [5] 的用法較特別,請思考思考

echo "Array size: ${#array[*]}"

echo "Array items:"
for item in ${array[*]}
do
printf " %s\n" $item
done

echo "Array indexes:"
for index in ${!array[*]}
do
printf " %d\n" $index
done

echo "Array items and indexes:"
for index in ${!array[*]}
do
printf "%4d: %s\n" $index ${array[$index]}
done

$ ./test.sh
Array size: 5
Array items:
one
two
three
four
five
Array indexes:
0
1
2
3
5
Array items and indexes:
0: one
1: two
2: three
3: four
5: five


底下再用一個範例來示範未使用雙引號及使用雙引號搭配 *, @ 的影響:

#!/bin/bash

array=("first item" "second item" "third" "item")

echo "Number of items in original array: ${#array[*]}"
for ix in ${!array[*]}
do
printf " %s\n" "${array[$ix]}"
done
echo

arr=(${array[*]}) # 引用所有元素展開後,因為元素值有空白,因而造成新陣列變異
echo "After unquoted expansion: ${#arr[*]}"
for ix in ${!arr[*]}
do
printf " %s\n" "${arr[$ix]}"
done
echo

arr=("${array[*]}") # 引用所有元素展開後,因為用雙引號括住,因而元素變成"一個"
echo "After * quoted expansion: ${#arr[*]}"
for ix in ${!arr[*]}
do
printf " %s\n" "${arr[$ix]}"
done
echo

arr=("${array[@]}") # 其影響請自行思考,非常重要
echo "After @ quoted expansion: ${#arr[*]}"
for ix in ${!arr[*]}
do
printf " %s\n" "${arr[$ix]}"
done

結果如下:
$ ./test2.sh
Number of items in original array: 4
first item
second item
third
item

After unquoted expansion: 6
first
item
second
item
third
item

After * quoted expansion: 1
first item second item third item

After @ quoted expansion: 4
first item
second item
third
item

2 意見:

Jack Online 提到...

Wade,Wade,為什麽在你的blog page會有廣告呢

頂你,呵呵,研究Geexbox去了

菠蘿麵包 提到...

這沒什麼好頂的吧?可能小說看太多。

為什麼會有廣告嗎?答案很簡單,我放的。我放廣告放很久了,也很久沒什麼人點廣告。google 的這項服務上網查查就有了。