Thêm một phần tử mới vào một mảng mà không chỉ định chỉ mục trong Bash


Câu trả lời:


1540

Có, có:

ARRAY=()
ARRAY+=('foo')
ARRAY+=('bar')

Tài liệu tham khảo Bash :

Trong ngữ cảnh mà một câu lệnh gán đang gán một giá trị cho biến shell hoặc chỉ mục mảng (xem Mảng), toán tử '+ =' có thể được sử dụng để chắp thêm hoặc thêm vào giá trị trước đó của biến.


21
Điều này chỉ hoạt động tốt với bash 3.2.48 (OS X 10.8.2). Lưu ý rằng đó ARRAYchỉ là một giữ chỗ cho một tên biến thực tế. Ngay cả khi các chỉ số mảng của bạn không tuần tự, việc nối thêm +=sẽ chỉ đơn giản là gán cho chỉ số cao nhất + 1.
mkuity0

3
Có một cái gì đó như thế trong phiên bản bash 4.2.24 (1)?
Ali Ismayilov

195
Điều quan trọng cần lưu ý là ARRAY + = ('foo') khác với ARRAY + = 'foo', nối thêm chuỗi 'foo' vào mục nhập có phím (?) Thấp nhất.
TheConstructor

8
Theo wiki.bash-hackers.org/scripting/bashchanges , cú pháp này lần đầu tiên xuất hiện trong phiên bản 3.1-alpha1.
David Yaw

39
@Jas: Để truy cập toàn bộ mảng, bạn phải sử dụng ${myarray[@]}- tham chiếu một biến mảng như thể nó là một vô hướng giống như truy cập phần tử 0 của nó; nói cách khác: $myarraygiống như ${myarray[0]}.
mkuity0

76

Như Dumb Guy chỉ ra, điều quan trọng cần lưu ý là mảng bắt đầu từ 0 và có tuần tự hay không. Vì bạn có thể thực hiện các bài tập và bỏ đặt các chỉ mục không liền kề ${#array[@]}không phải lúc nào cũng là mục tiếp theo ở cuối mảng.

$ array=(a b c d e f g h)
$ array[42]="i"
$ unset array[2]
$ unset array[3]
$ declare -p array     # dump the array so we can see what it contains
declare -a array='([0]="a" [1]="b" [4]="e" [5]="f" [6]="g" [7]="h" [42]="i")'
$ echo ${#array[@]}
7
$ echo ${array[${#array[@]}]}
h

Đây là cách lấy chỉ mục cuối cùng:

$ end=(${!array[@]})   # put all the indices in an array
$ end=${end[@]: -1}    # get the last one
$ echo $end
42

Điều đó minh họa làm thế nào để có được phần tử cuối cùng của một mảng. Bạn sẽ thường thấy điều này:

$ echo ${array[${#array[@]} - 1]}
g

Như bạn có thể thấy, bởi vì chúng ta đang xử lý một mảng thưa thớt, đây không phải là yếu tố cuối cùng. Điều này hoạt động trên cả mảng thưa thớt và tiếp giáp, mặc dù:

$ echo ${array[@]: -1}
i

3
Công cụ tuyệt vời; không bao giờ biết rằng cú pháp trích xuất chuỗi con cũng có thể được áp dụng cho các mảng; các quy tắc, được xác định bằng thử nghiệm và lỗi, là (bash 3.2.48): ${array[@]: start[:count]}Trả về số lượng elems. hoặc, nếu không được chỉ định, tất cả các elems còn lại . bắt đầu từ elem sau: - Nếu bắt đầu> = 0: từ elem. có chỉ số> = bắt đầu. - Nếu bắt đầu <0: từ elem. có chỉ số là (chỉ số mảng cuối + 1) - abs (bắt đầu); CAVEAT: nếu abs (bắt đầu)> (chỉ mục mảng cuối + 1), chuỗi null được trả về. Nếu số lượng được chỉ định, vì nhiều phần tử được trả về, ngay cả khi các chỉ số của chúng không liền kề từ đầu.
mkuity0

3
@mkuity: Trong Bash 4.2, bạn có thể sử dụng các chỉ số mảng âm để truy cập các phần tử đếm từ cuối mảng. ${array[-1]}
Tạm dừng cho đến khi có thông báo mới.

Đó là điều tốt để biết, cảm ơn. OS X (kể từ ngày 10.8.2) vẫn sử dụng 3.2.48 và stackoverflow.com/questions/10418616/, nói với tôi rằng, thật không may, "Apple sử dụng một phiên bản Bash khá cũ, vì họ không gửi mã được cấp phép theo GPL3. "
mkuity0

49
$ declare -a arr
$ arr=("a")
$ arr=("${arr[@]}" "new")
$ echo ${arr[@]}
a new
$ arr=("${arr[@]}" "newest")
$ echo ${arr[@]}
a new newest

8
tốt cho các phiên bản bash không hỗ trợ ngữ nghĩa của toán tử + = được giải thích bởi e-t172
akostadinov

12
một giải pháp tương thích ngược tốt, nhưng hãy cẩn thận rằng nếu bất kỳ yếu tố hiện có nào có không gian trong đó, chúng sẽ được chia thành nhiều yếu tố; sử dụng arr=("${arr[@]}" "new")nếu bạn có các yếu tố có khoảng trắng trong đó
kbolino 17/03/13

1
Điều này cũng có thể được sử dụng để đẩy trước mảng, đó là những gì tôi cần.
Tomáš Zato - Phục hồi Monica

29

Nếu mảng của bạn luôn tuần tự và bắt đầu từ 0, thì bạn có thể làm điều này:

array[${#array[@]}]='foo'

# gets the length of the array
${#array_name[@]}

Nếu bạn vô tình sử dụng khoảng trắng giữa các dấu bằng:

array[${#array[@]}] = 'foo'

Sau đó, bạn sẽ nhận được một lỗi tương tự như:

array_name[3]: command not found

5
Có, bạn có thể, nhưng +=cú pháp (xem câu trả lời của @ e-t172) là (a) đơn giản hơn và (b) cũng hoạt động với các mảng không liền kề và / hoặc không bắt đầu bằng 0.
mkuity0

Thành thật mà nói, giải pháp này (đối với tôi) đang hoạt động tốt hơn "+ =", bởi vì với độ dài đôi khi sai (tăng hai khi thêm một yếu tố) ... vì vậy tôi thích trả lời này! :)
Pierpaolo Cira

Điều này cũng hoạt động trong các phiên bản trước của bash, trước khi +=được thêm vào, ví dụ phiên bản 2
Zoey Hewll

1
Điều này cũng hoạt động khi các phần tử của bạn có khoảng trắng trong chúng - $arr += ($el)dường như phân tách chuỗi theo khoảng trắng và thêm từng phần tử.
Tối đa

5

Với một mảng được lập chỉ mục, bạn có thể làm một cái gì đó như thế này:

declare -a a=()
a+=('foo' 'bar')
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.