2011-01-03 27 views
25

Giả sử tôi có một số bash mảng:Bash địa chỉ mảng gián tiếp?

A1=(apple trees) 
A2=(building blocks) 
A3=(color television) 

Và chỉ số J=2, làm thế nào để có được nội dung mảng của A2?

+0

Điều này rất hay. Tôi coi bản thân mình là một chuyên gia bash và tôi luôn luôn theo giả định rằng bash không thể làm mảng indirection như '$ {! Ind [@]}' nhưng tôi không bao giờ nghĩ để giới thiệu một temp var để giải quyết nó. – SiegeX

+0

Câu hỏi/câu trả lời thú vị! –

+0

Bạn nên đăng câu trả lời của mình dưới dạng câu trả lời. Bạn sẽ có thể chấp nhận nó khi hết hạn thời gian. Đây là một ví dụ về cách thông thường mà các mảng được sử dụng với sự vô hướng: 'd = 13; e = 24; f = 35; a = (d e f); echo $ {! a [1]} 'kết quả là" 24 ". –

Trả lời

21

Tôi đã tìm ra giải pháp, điều này có thể được thực hiện bằng cách:

$ Aref=A$J 
$ echo ${!Aref} 
building 
$ Aref=A$J[1] 
$ echo ${!Aref} 
blocks 
$ Aref=A$J[@] 
$ echo "${!Aref}" 
building blocks 
+2

Làm thế nào bạn có thể gán cho, nói, 'A $ J'? Bạn cần một tên mà không cần mở rộng để gán cho, nhưng 'A $ J = (...)' không hoạt động. – musiphil

+0

đó là chữ cái "A" theo sau là nội dung của biến "J". Nếu J == 2, thì bạn có thể thấy nó là A + $ {J} == A2 –

+0

@musiphil, 'printf -v" Giá trị $ J "'% s'" để gán "' sẽ thực hiện thủ thuật. Xem [BashFAQ # 6] (http://mywiki.wooledge.org/BashFAQ/006). –

17

Đó là giá trị cần lưu ý, rằng ngay cả một chỉ số sẽ được thay thế vào thời điểm đó biến được đánh giá:

$ A2=(building blocks) 
$ Aref=A2[index] 
$ index=1 
$ echo "${!Aref}" 
blocks 
+2

** FANTASTIC. ** năm của shell scripting + đọc hướng dẫn sử dụng ít nhất một tá lần + * cố gắng rõ ràng chính xác điều này * thất bại để bề mặt đá quý nhỏ này! lưu ý, giống như chỉ mục theo nghĩa đen, ** bất kỳ biểu thức số học nào là hợp lệ, bao gồm cả mở rộng lồng nhau **, ví dụ: 'cycle = (0 1 2); ref = 'cycle [i ++% $ {# cycle [*]}]'; echo $ {! ref} $ {! ref} $ {! ref} $ {! ref} $ {! ref} $ {! ref} # => 0 1 2 0 1 2' – anthonyrisinger

+0

Tôi tự hỏi nếu đây là một tính năng rõ ràng dự định như vậy, hoặc nếu chúng ta đang khai thác tác dụng phụ của việc mở rộng gián tiếp, mà có thể âm thầm biến mất khỏi các bản phát hành trong tương lai. – davide

+0

@anthonyrisinger điều này khá thú vị thx :) –

2

Hôm nay (với bash 4.3 và mới hơn), việc thực hành tốt nhất là sử dụng nameref hỗ trợ:

A1=(apple trees) 
A2=(building blocks) 
A3=(color television) 
J=2 

declare -n A="A$J" 
printf '%q\n' "${A[@]}" 

... sẽ phát ra đúng cách:

building 
blocks 

Điều này cũng có sẵn dưới dạng nameref A="A$J" trên ksh93. Xem BashFAQ #6 để biết chi tiết.

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