Làm thế nào để làm tròn chuyến đi một mảng kết hợp bash vào một tệp văn bản?


9

Tôi muốn ghi nhớ một mảng kết hợp giữa các lần chạy script khác nhau. Những gì tôi có cho đến nay là đã cho một tệp văn bản chứa một cặp khóa / giá trị:

(
[james]=bond
)

Là một tập lệnh để tải nó vào một mảng kết hợp, thêm vào nó, sau đó lặp lại nó theo cách có thể được chuyển hướng vào một tệp thứ hai:

#!/bin/bash
file=`cat $1`
key=$2
value=$3
declare -A row="$file"
row[$key]=$value
echo "("
for server in "${!row[@]}"
    do echo "[$server]=${row[$server]}"; done
echo ")"

sau đó tôi có thể chạy nó như:

./arrays.sh file1 honey rider > file2 ; mv file2 file1

Bố thí

(
[james]=bond
[honey]=rider
)

Tuy nhiên, nó có vẻ rất clunky. Có cách nào sạch hơn để làm điều này?


4
declare -p hash > fileđể lưu hashmảng kết hợp. source fileđể khôi phục lại.
Stéphane Chazelas

2
Có lẽ nó nên arrays.bash...
mikeerv

Câu trả lời:


10

Trong bash, declare -pcó thể được sử dụng để kết xuất định nghĩa của một biến là mã shell sẵn sàng để được giải thích, vì vậy bạn có thể thực hiện cập nhật cho tệp bằng:

#! /bin/bash -
file=${1?}; shift
declare -A row
source -- "$file" || exit
while [ "$#" -ge 2 ]; do
  row[$1]=$2
  shift 2
done
declare -p row > "$file"

Lưu ý rằng điều quan trọng là tệp được tạo và có nguồn gốc trong cùng một miền (ít nhất là cùng LC_CTYPEloại).

Một tập lệnh để hiển thị nội dung của tệp sẽ là:

#! /bin/bash -
file=${1?}; shift
declare -A row
source -- "$file"
for i in "${!row[@]}"
do
  printf 'key  : %s\n' "$i"
  printf 'value: %s\n' "${row[$i]}"
done

Hoan hô cho các thông số tự đủ điều kiện! Nhưng một chuỗi lỗi cụ thể hơn sẽ không hữu ích hơn?
mikeerv

@mikeerv, chắc chắn, nhưng đó là ngoài câu trả lời. Bằng mọi cách, xin vui lòng thêm kiểm tra cú pháp thích hợp khi thích hợp. Người ta cũng có thể muốn kiểm tra xem có một số lượng đối số chẵn sau tên tệp (hoặc sử dụng đối số đơn lẻ làm phương tiện để xóa một phần tử không).
Stéphane Chazelas

Tôi không biết ... Có lẽ đừng yêu cầu tôi chỉnh sửa ... Tôi không được phép mời ma cà rồng vào ... Nhưng những gì đã xong, tôi đoán vậy.
mikeerv

ồ xin lỗi. Tôi đoán tôi không nên có nghĩa đen? Tôi đã làm như bạn yêu cầu và làm cho nó mạnh mẽ hơn một chút mà không làm phức tạp nó.
mikeerv

2
@ ec2011, với các phiên bản gần đây của bash(gần đây hơn là có sẵn tại thời điểm câu trả lời được viết), bạn có thể sử dụng readarray -td '' arrayđể đọc các bản ghi được phân định bằng NUL thành một mảng thông thường và sau đó chuyển đổi nó thành một mảng kết hợp.
Stéphane Chazelas
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.