Trước hết, bạn không cần phải sử dụng $(echo $FRUITS)
trong for
tuyên bố. Sử dụng chỉ $FRUITS
là đủ. Sau đó, bạn có thể loại bỏ một trong các dòng bên trong vòng lặp, bằng cách sử dụng eval
.
Việc eval
đơn giản chỉ ra bash để thực hiện đánh giá thứ hai cho câu lệnh sau (tức là nhiều hơn so với đánh giá bình thường của nó). Người \$
sống sót đánh giá đầu tiên là $
, và đánh giá tiếp theo sau đó coi đây $
là sự bắt đầu của một tên biến, phân giải thành "Màu vàng", v.v.
Bằng cách này, bạn không cần phải có một bước riêng biệt tạo nên một chuỗi tạm thời (đó là điều tôi tin là mục đích chính của câu hỏi của bạn).
for fruit in $FRUITS ;do
eval echo $fruit is \$${fruit}_COLOUR
done
Đối với một phương pháp thay thế, như Patrick đã đề cập trong một nhận xét (ở trên), thay vào đó, bạn có thể sử dụng một mảng kết hợp , trong đó chỉ mục của một phần tử không cần phải là một số nguyên. Bạn có thể sử dụng một chuỗi, chẳng hạn như tên của một loại trái cây. Dưới đây là một ví dụ, sử dụng mảng kết hợp của bash:
# This declares an associative array (It unsets it if it already exists)
declare -A colour
colour['BANANA']="Yellow"
colour["APPLE"]="Green or Red"
colour[MARTIAN ORANGE]="Blue"
for fruit in BANANA APPLE "MARTIAN ORANGE" ;do
echo "$fruit" is "${colour[$fruit]}"
done
!
cú pháp là một lá cờ trên thay biến mà về cơ bản nói “thay hai lần”. Nó không thay đổi yêu cầu rằng những gì bên trong${…}
phải là một tên biến. Vì vậy, không, bạn không thể tránh sử dụng một biến có chứa tên, trừ khi bạn sử dụng một phương thức khác (eval
).