In một mảng thành một tệp với mỗi phần tử của mảng trong một dòng mới trong bash


13

Tôi đang thử nội dung của một mảng thành một tệp với mỗi phần tử của mảng trong một dòng mới trong tệp.

IFS=$'\n'   
echo "${mtches[@]}" > sample1.txt 


Nội dung của mtches là "qwe" và "asd". Nhưng sample1.txttập tin chứa qwe asdtrong một dòng duy nhất. Tại sao nó không lấy giá trị IFS vào hình ảnh?

Câu trả lời:


16

Bạn nên sử dụng printfthay vìecho :

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

Nếu mtchestrống mà vẫn xuất ra một dòng trống. Để giải thích cho điều đó:

{ [ "${#mtches[@]}" -eq 0 ] || printf '%s\n' "${mtches[@]}"; } > file

Trong bash(và cũng vỏ POSIX), bạn thường sử dụng mảng Positional Parameters như "$@"thay vì "$*", trừ khi bạn có một lý do đặc biệt. Điều đó cũng đúng trong các shell hỗ trợ các mảng thông thường, từ man bash - phần Mảng :

Bất kỳ phần tử nào của một mảng có thể được tham chiếu bằng $ {name [subscript]}. Các dấu ngoặc nhọn được yêu cầu để tránh xung đột với các toán tử mở rộng tên tệp của shell. Nếu chỉ mục là '@' hoặc '*', từ sẽ mở rộng cho tất cả các thành viên của tên mảng. Các mục con này chỉ khác nhau khi từ xuất hiện trong dấu ngoặc kép. Nếu từ được trích dẫn kép, $ {name [*]} sẽ mở rộng thành một từ duy nhất với giá trị của từng thành viên mảng được phân tách bằng ký tự đầu tiên của biến IFS và $ {name [@]} mở rộng từng thành phần của tên đến một từ riêng biệt. Khi không có thành viên mảng, $ {name [@]} sẽ mở rộng thành không có gì. Nếu việc mở rộng trích dẫn kép xảy ra trong một từ, thì việc mở rộng tham số đầu tiên được nối với phần đầu của từ gốc và việc mở rộng tham số cuối cùng được nối với phần cuối của từ gốc.

Chỉ sử dụng "${array[*]}" khi bạn muốn nối tất cả các thành phần mảng thành một chuỗi.


Làm thế nào mà làm cho một sự khác biệt?
Ashwin


7

Bạn muốn sử dụng ${mtches[*]} thay thế.

Khi bạn sử dụng "${mtches[@]}", không có vấn đề gì về giá trị của $IFSnó, bash sẽ chia mảng thành nhiều đối số. Những gì bạn muốn là một đối số duy nhất với mỗi phần tử mảng được nối bởi \n.${mtches[*]}hoàn thành việc này

Cũng như một cách thiết lập tạm thời $IFS, bạn có thể làm:

( IFS=$'\n'; echo "${mtches[*]}" > sample1.txt )

Sau đó, bạn không phải bận tâm với việc đặt lại.


pubs.opengroup.org/onlinepub/9699919799/utilities/ trên <- Tham chiếu POSIX (điều này không chỉ áp dụng cho bash).
Mat

Hoặc sử dụng printf...
jasonwryan

2

Sử dụng cho :

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

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

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

Sử dụng tên cơ sở ; lưu ý điề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 được đưa ra theo thứ tự:

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

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.