2013-10-17 21 views
29

tôi có một loạt các ứng dụng, khởi tạo như thế này:Làm thế nào để sao chép một mảng trong Bash?

depends=(cat ~/Depends.txt) 

Khi tôi cố gắng phân tích danh sách và sao chép nó vào một mảng mới sử dụng,

for i in "${depends[@]}" 
    if [ $i #isn't installed ]; then 
     newDepends+=("$i") 
    fi 
done 

gì xảy ra là chỉ là người đầu tiên yếu tố của gió phụ thuộc vào newDepends.

for i in "${newDepends[@]}" 
    echo $i 
done 

^^ Điều này sẽ chỉ xuất hiện một điều. Vì vậy, tôi đang cố gắng tìm ra lý do tại sao vòng lặp của tôi là chỉ di chuyển phần tử đầu tiên. Toàn bộ danh sách ban đầu phụ thuộc vào, do đó, nó không phải là, nhưng tôi tất cả ra khỏi ý tưởng.

+0

Điều đó có vẻ ổn với tôi. Bạn có chắc chắn bài kiểm tra "chưa được cài đặt" của bạn hoạt động chính xác không? – rici

+4

Có lỗi đánh máy nào trong câu hỏi của bạn không? 'depends' sẽ bao gồm 2 từ,' cat' và '~/Depends', không phải nội dung của' ~/Depends.txt'. – chepner

Trả lời

1

Bạn có thể sao chép một mảng bằng cách chèn các phần tử của mảng đầu tiên vào bản sao bằng cách xác định các chỉ số:

#!/bin/bash 

array=(One Two Three Go!); 
array_copy(); 

let j=0; 
for ((i=0; i<${#array[@]}; i++) 
do 
    if [[ $i -ne 1 ]]; then # change the test here to your 'isn't installed' test 
     array_copy[$j]="${array[$i]} 
     let i+=1; 
    fi 
done 

for k in "${array_copy[@]}"; do 
    echo $k 
done 

Sản lượng này sẽ là:

One 
Three 
Go! 

Một tài liệu hữu ích về mảng bash là trên TLDP.

-3

Tôi đã phát hiện những gì đã sai .. Nếu thử nghiệm chưa được cài đặt của tôi là hai vòng lặp loại bỏ ký tự dư thừa khỏi tên tệp và nhổ chúng ra nếu chúng tồn tại trên một máy chủ web nhất định. Điều mà nó không làm là xóa dấu gạch ngang. Vì vậy, khi nó kiểm tra nó trực tuyến cho sự sẵn có, họ đã được phân tích. Vì "tệp" tồn tại, nhưng "tệp-" thì không.

67
a=(foo bar "foo 1" "bar two") #create an array 
b=("${a[@]}")     #copy the array in another one 

for value in "${b[@]}" ; do #print the new array 
echo "$value" 
done 
+2

Có ổn không khi viết b = ($ {a [@]})? – Indicator

+4

cố gắng thực hiện lệnh với các sửa đổi của bạn, bạn sẽ undestand lý do tại sao nó không chính xác để viết mà không trích dẫn ...giá trị "foo 1" sẽ không được hiển thị như nó shoudl nhưng nó sẽ tạo ra nhiều giá trị hơn cho foo mảng VÀ 1, quầy bar và hai, thay vì "foo 1" và "thanh hai" – user1088530

+0

@Indicator Bạn sẽ có vấn đề với không gian! –

3

Các giải pháp được đưa ra trong các câu trả lời khác sẽ không hoạt động đối với mảng kết hợp hoặc cho mảng có chỉ số không tiếp giáp. Dưới đây là là một giải pháp tổng quát hơn:

declare -A arr=([this]=hello [\'that\']=world [theother]='and "goodbye"!') 
temp=$(declare -p arr) 
eval "${temp/arr=/newarr=}" 

diff <(echo "$temp") <(declare -p newarr | sed 's/newarr=/arr=/') 
# no output 

Và khác:

declare -A arr=([this]=hello [\'that\']=world [theother]='and "goodbye"!') 
declare -A newarr 
for idx in "${!arr[@]}"; do 
    newarr[$idx]=${arr[$idx]} 
done 

diff <(echo "$temp") <(declare -p newarr | sed 's/newarr=/arr=/') 
# no output 
+0

giải pháp đầu tiên của bạn không thể trở thành một chức năng, bởi vì 'eval "tuyên bố -A newarr = ..." 'hiệu quả sẽ khai báo một * địa phương * mảng' newarr' shadowing biến thực tế từ môi trường mẹ. Nó có thể là một tùy chọn để loại bỏ 'declare -A' để chỉ 'newarr =…' còn lại, nhưng có những vấn đề thoát khỏi đường dẫn đó. –

2

Bắt đầu với Bash 4.3, bạn có thể làm

$ alpha=(bravo charlie 'delta 3' '' foxtrot) 

$ declare -n golf=alpha 

$ echo "${golf[2]}" 
delta 3 
+11

Câu trả lời này không đúng. Trong khi '' 'declare -n''' hữu ích, nó chỉ tạo tham chiếu tới mảng ban đầu, nó không sao chép nó, đó là câu hỏi đang hỏi. – niieani

6

Cách này đơn giản nhất để sao chép một mảng không kết hợp trong bash là:

arrayClone=("${oldArray[@]}")

hoặc để thêm các yếu tố để một mảng preexistent:

someArray+=("${oldArray[@]}")

Newlines/chỗ/IFS trong các yếu tố sẽ được giữ lại.

Để sao chép mảng kết hợp, các giải pháp của Isaac hoạt động tốt.

+0

anh ta dường như không làm việc cho tôi: '' ' $ a1 = (người đàn ông harry lớn); $ a2 = ("$ {! A1 [@]}"); $ echo "$ {a2 [0]}"; $ echo "$ {a2 [1]}"; 1; $ '' ' –

+2

hey @FelipeAlvarez - thực sự là '' là không cần thiết, tôi đã sửa câu trả lời của tôi – niieani

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