2011-07-25 32 views
9

Tôi có thể loại bỏ eval tại đây không? Tôi đang cố gắng để thiết lập $current_database với biến thích hợp xác định bởi người dùng nhập vào (quốc gia và hành động)biến hệ vỏ lồng nhau mà không sử dụng eval

# User input 
country="es" 
action="sales" 

# Possible variables for current_database 
final_es_sales_path="blahblah/es/sales.csv" 
final_en_support_path="yadayada/en/support.csv" 
final_it_inventory_path="humhum/it/inventory.csv" 
... 

current_database=$(eval echo \${final_${country}_${action}_path}) 
+1

Chỉ cần lưu ý: 'en',' es', 'it' là các mã ngôn ngữ ([ISO 639-1] (http://en.wikipedia.org/wiki/ISO_639)), không phải mã quốc gia. Mã quốc gia ([ISO 3166-1] (http://en.wikipedia.org/wiki/ISO_3166-1)) giống như sau: 'ES',' MX', 'GB',' US', 'IT' (để đặt tên cho một số quốc gia nơi các ngôn ngữ này được nói). –

Trả lời

9

Bạn có thể sử dụng các mảng kết hợp, tham gia các giá trị của cả hai biến. Ví dụ:

declare -A databases 
# initialization 
databases["es:sales"]="blahblah/es/sales.csv" 
databases["en:support"]="yadayada/en/support.csv" 

Sau đó, bạn có thể nhận được cơ sở dữ liệu chỉ bằng cách:

echo ${databases["${country}:${action}"]} 

này có lợi thế là có tên cơ sở dữ liệu được thu thập bởi chỉ có một biến.

+0

Đẹp. Vì vậy, tôi chỉ có thể làm: 'current_database = $ {databases [" $ {country}: $ {action} "]}'. Tôi tự hỏi liệu có cách nào để làm điều đó trong Bash 3.x – nachocab

+0

một lưu ý để xử lý sự cố: nếu bạn quên thực hiện 'declare -A' thì việc mở rộng sẽ luôn dẫn đến phần tử cuối cùng mà bạn tạo (trong đoạn mã trên) , 'databases [" vi: support "]' – Jeff

0

Liệu không

current_database=${final_${country}_${action}_path} 

làm những gì bạn muốn?

Chỉnh sửa: Không, không. Mở rộng tham số chỉ hoạt động trên một từ (đối với tên thông số) và $ không được phép trong một từ. Có thể sử dụng mở rộng tham số lồng nhau trong các phần khác của các phiên bản phức tạp hơn (với giới hạn, thay thế, giá trị mặc định, v.v.), đó là lý do tại sao một số biến thể mở rộng được liệt kê ở đây (của tôi):

Khi niềng răng được sử dụng, phù hợp với kết thúc cú đúp là lần đầu tiên '}' không trốn thoát bằng xuyệc ngược hoặc trong một chuỗi trích dẫn, và không thuộc phạm vi mở rộng số học nhúng, lệnh thay thế, hoặc mở rộng tham số.

Xin lỗi. Hình như eval và mảng là đặt cược tốt nhất của bạn, sau đó.

+0

Không, đó là một sự thay thế xấu. $ {final _ $ {country} _ $ {action} _path}: thay thế xấu – nachocab

2

Thực ra, bạn có thể và không cần sử dụng mảng kết hợp (không phải là giải pháp tồi, hãy nhớ bạn). Bạn có thể sử dụng giải pháp tương tự như sau:

> current_database=$(echo final_${country}_${action}_path) 
> echo $current_database 
final_es_sales_path 
> current_database=${!current_database} 
> echo $current_database 
blahblah/es/sales.csv 

Điều này tránh mảng và bằng cách sử dụng mở rộng gián tiếp. Điều này dường như đã được giới thiệu trong phiên bản thứ hai của Bash, do đó, khá nhiều bất kỳ máy nào có thể làm điều đó.

+0

điều này * là * tốt như vậy - quá tệ có thể không phải là nhiều câu trả lời được chấp nhận – Jeff

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