2013-03-28 28 views
118

Làm cách nào để in phần tử mảng của mảng Bash trên các dòng riêng biệt? Cái này hoạt động, nhưng chắc chắn có một cách tốt hơn:Các phần tử mảng in bash trên các dòng riêng biệt

$ my_array=(one two three) 
$ for i in ${my_array[@]}; do echo $i; done 
one 
two 
three 

thử cái này nhưng nó đã không làm việc:

$ IFS=$'\n' echo ${my_array[*]} 
one two three 

Trả lời

243

Hãy thử làm điều này:

$ printf '%s\n' "${my_array[@]}" 

Sự khác biệt giữa [email protected]$*:

  • Không được bỏ phiếu, kết quả không được chỉ định. Trong Bash, cả hai mở rộng để phân tách args và sau đó là wordsplit và globbed.

  • Quoted, "[email protected]" mở rộng mỗi yếu tố như một đối số riêng biệt, trong khi "$*" mở rộng đến args sáp nhập vào một đối số: "$1c$2c..." (nơi c là char đầu tiên của IFS).

Bạn hầu như luôn muốn "[email protected]". Tương tự cho "${arr[@]}".

Luôn báo giá cho họ!

+4

Và lưu ý, dấu ngoặc kép quanh tham chiếu biến là quan trọng nếu bạn muốn đảm bảo rằng các phần tử có không gian nội bộ không bị phân tách vô tình. – danfuzz

+1

@sputnick: không hoạt động, các phần tử mảng kết thúc trên một dòng –

+0

Bạn có chắc là bạn đã sử dụng '[@]' chứ không phải '[*]'? Nó tạo nên sự khác biệt. – danfuzz

48

Chỉ cần trích lập luận để echo:

(IFS=$'\n'; echo "${my_array[*]}") 

vỏ phụ giúp khôi phục lại sau khi sử dụng IFS

+3

xin lỗi về sự thật, tôi đã chuyển dấu kiểm của mình sang sputnick, mặc dù thích giải pháp của bạn tốt hơn, chỉ vì tôi đã học về chức năng 'printf'. –

+2

Cảm ơn câu trả lời này - Tôi thích nó! Các bài tập quá xấu xảy ra sau khi mở rộng để 'IFS = $ '\ n' echo '$ {my_array [*]}" 'không hoạt động. Oh well! – cxw

3

Tôi đã thử các câu trả lời ở đây trong một người khổng lồ cho ... nếu vòng lặp, nhưng didn' t nhận được bất kỳ niềm vui - vì vậy tôi đã làm điều đó như thế này, có lẽ lộn xộn nhưng đã làm các công việc:

# EXP_LIST2 is iterated  
# imagine a for loop 
    EXP_LIST="List item"  
    EXP_LIST2="$EXP_LIST2 \n $EXP_LIST" 
done 
echo -e $EXP_LIST2 

mặc dù đó thêm một không gian vào danh sách, đó là tốt - tôi muốn nó thụt vào một chút. Cũng giả sử "\ n" có thể được in trong $ EP_LIST gốc.

+1

Không giống như một ví dụ hoàn chỉnh. – kenorb

22

Sử dụng cho:

for each in "${alpha[@]}" 
do 
    echo "$each" 
done 

Sử dụng lịch sử; lưu ý này sẽ thất bại nếu giá trị của bạn chứa !:

history -p "${alpha[@]}" 

Sử dụng basename; lưu ý này sẽ thất bại nếu giá trị của bạn chứa /:

basename -a "${alpha[@]}" 

Sử dụng shuf; lưu ý rằng kết quả có thể không đi ra theo trình tự:

shuf -e "${alpha[@]}" 
+5

"shuf" ... "có thể không xuất hiện theo thứ tự" ... vui nhộn. – Walf

1

Một biến thể hữu ích là ống để tr:

echo ${my_array[@]} | tr " " "\n"

này có vẻ đơn giản và nhỏ gọn

+3

Trừ trường hợp ngắt này trên 'my_array = (" một hai "ba)' –

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