cara pulang pergi array asosiatif bash ke file teks?

9

Saya ingin mengingat array asosiatif antara berbagai skrip berjalan. Apa yang saya miliki sejauh ini adalah bahwa diberikan file teks yang berisi satu pasangan kunci / nilai:

(
[james]=bond
)

Adalah skrip untuk memuatnya ke dalam array asosiatif, tambahkan padanya, kemudian gema dengan cara yang dapat diarahkan ke file kedua:

#!/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 ")"

maka saya bisa menjalankannya sebagai:

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

Memberi

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

Namun sepertinya sangat kikuk. Apakah ada cara yang lebih bersih untuk melakukan ini?

simbo1905
sumber
4
declare -p hash > fileuntuk menyimpan hasharray asosiatif. source fileuntuk memulihkan.
Stéphane Chazelas
2
Mungkin seharusnya arrays.bash...
mikeserv

Jawaban:

10

Di bash, declare -pdapat digunakan untuk membuang definisi variabel sebagai kode shell siap ditafsirkan, sehingga Anda dapat melakukan pembaruan ke file dengan:

#! /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"

Perhatikan bahwa penting agar file dibuat dan bersumber di lokal yang sama (setidaknya LC_CTYPEkategori yang sama ).

Sebuah skrip untuk menampilkan konten file adalah:

#! /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
Stéphane Chazelas
sumber
Hore untuk parameter yang memenuhi syarat sendiri! Tetapi apakah string kesalahan yang lebih spesifik tidak akan lebih berguna?
mikeserv
@ mikeserv, tentu saja, tapi itu tidak penting dari jawabannya. Dengan segala cara, harap tambahkan pemeriksaan sintaksis yang sesuai. Seseorang mungkin juga ingin memeriksa bahwa ada sejumlah argumen setelah nama file (atau menggunakan argumen tunggal ganjil sebagai sarana untuk menghapus elemen tunggal).
Stéphane Chazelas
Saya tidak tahu ... Mungkin tidak meminta saya untuk mengedit ... Anda tidak seharusnya mengundang vampir masuk ... Tapi apa yang dilakukan sudah selesai, saya kira.
mikeserv
Oh maaf. Saya kira saya seharusnya tidak menganggapnya secara harfiah? Saya melakukan apa yang Anda minta dan membuatnya sedikit lebih kuat tanpa menyulitkannya.
mikeserv
2
@ ec2011, dengan versi terbaru bash(lebih baru daripada yang tersedia pada saat jawaban itu ditulis), Anda dapat menggunakan readarray -td '' arrayuntuk membaca catatan yang dibatasi NUL menjadi larik reguler dan kemudian mengonversinya menjadi larik asosiatif.
Stéphane Chazelas