2010-06-24 38 views
224

Dựa trên một mảng kết hợp trong tập lệnh Bash, tôi cần lặp lại nó để lấy khóa và giá trị.Cách lặp qua các mảng liên kết trong Bash

#!/bin/bash 

declare -A array 
array[foo]=bar 
array[bar]=foo 

Tôi thực sự không hiểu cách lấy khóa khi đang sử dụng vòng lặp for-in.

+6

$ tuyên bố -A mảng = ([foo] = bar [thanh] = foo) # Khởi tạo tất cả cùng một lần – anisbet

+2

Đối với một danh sách nhỏ các giá trị khóa bạn có thể xem xét điều này: 'cho i in a, b c_s, d; làm KEY = $ {i%, *}; VAL = $ {i # *,}; echo $ KEY "XX" $ VAL; done' – math

Trả lời

400

Các phím được truy cập sử dụng một dấu chấm than: ${!array[@]}, các giá trị được truy cập bằng cách sử dụng ${array[@]}.

Bạn có thể duyệt qua các cặp khóa/giá trị như thế này:

for i in "${!array[@]}" 
do 
    echo "key : $i" 
    echo "value: ${array[$i]}" 
done 

Lưu ý việc sử dụng dấu ngoặc kép quanh biến trong báo cáo for (cộng với việc sử dụng các @ thay vì *). Điều này là cần thiết trong trường hợp bất kỳ phím nào bao gồm dấu cách.

Sự nhầm lẫn trong câu trả lời khác đến từ thực tế là câu hỏi của bạn bao gồm "foo" và "bar" cho cả hai khóa các giá trị.

+2

Điều này bây giờ nếu gán tất cả các khóa cho một mảng: 'array = ($ {! hash [@]})' –

+7

@ Michael-O: Bạn cần để báo giá mở rộng tham số để bảo vệ các khóa có thể có khoảng trắng: 'array = (" $ {! hash [@]} ")' –

+0

@DennisWilliamson, cảm ơn rất nhiều. Tôi không có điều này trong đầu. –

35

Bạn có thể truy cập vào các phím với ${!array[@]}:

bash-4.0$ echo "${!array[@]}" 
foo bar 

Sau đó, lặp lại trên các cặp khóa/giá trị rất dễ dàng:

for i in "${!array[@]}" 
do 
    echo "key :" $i 
    echo "value:" ${array[$i]} 
done 
+0

hoàn hảo - cảm ơn! – pex

+1

Tôi đã có "!" - thậm chí không nhận thấy, không có gì, xin lỗi .. :) – pex

4

Sử dụng chức năng này bậc cao để ngăn chặn sự dụ pyramid of doom

foreach(){ 
    arr="$(declare -p $1)" ; eval "declare -A f="${arr#*=}; 
    for i in ${!f[@]}; do $2 "$i" "${f[$i]}"; done 
} 

:

$ bar(){ echo "$1 -> $2"; } 
$ declare -A foo["flap"]="three four" foo["flop"]="one two" 
$ foreach foo bar 
flap -> three four 
flop -> one two 
+1

Tôi không chắc cách áp dụng điều này? Không phải là kim tự tháp của doom một vấn đề thẩm mỹ hoàn toàn và thực sự chỉ áp dụng trong các ngôn ngữ hướng đối tượng? –

+1

bạn có thể giải thích nó không? Chức năng foreach hơi phức tạp. Tôi không hiểu. –

Các vấn đề liên quan