Jika Anda memiliki Git tersedia dan OK dengan kendala tidak dapat menggunakan garis bawah pada nama-nama kunci, Anda dapat menggunakan git config
sebagai parser / editor INI untuk keperluan umum.
Ini akan menangani parsing keluar pasangan kunci / nilai dari sekitar =
dan membuang spasi kosong, ditambah Anda mendapatkan komentar (keduanya ;
dan #
) dan ketik paksaan pada dasarnya gratis. Saya telah menyertakan contoh kerja lengkap untuk input OP .ini
dan output yang diinginkan (array asosiatif Bash), di bawah ini.
Namun, diberikan file konfigurasi seperti ini
; mytool.ini
[section1]
inputdir = ~/some/dir
enablesomefeature = true
enablesomeotherfeature = yes
greeting = Bonjour, Monde!
[section2]
anothersetting = 42
... asalkan Anda hanya membutuhkan solusi cepat dan kotor, dan tidak menikah dengan gagasan memiliki pengaturan dalam array asosiatif Bash, Anda bisa lolos dengan sesedikit:
eval $(git config -f mytool.ini --list | tr . _)
# or if 'eval' skeeves you out excessively
source <(git config -f mytool.ini --list | tr . _)
yang membuat variabel lingkungan bernama sectionname_variablename
di lingkungan saat ini. Ini, tentu saja, hanya berfungsi jika Anda dapat percaya bahwa tidak ada nilai Anda yang akan mengandung suatu periode atau spasi (lihat di bawah untuk solusi yang lebih kuat).
Contoh sederhana lainnya
Mengambil nilai arbitrer, menggunakan fungsi shell untuk menyimpan pengetikan:
function myini() { git config -f mytool.ini; }
Sebuah alias akan baik-baik saja, di sini juga, tetapi itu biasanya tidak diperluas dalam skrip shell [ 1 ], dan lagi pula alias digantikan oleh fungsi shell "untuk hampir setiap tujuan," [ 2 ], menurut halaman manual Bash .
myini --list
# result:
# section1.inputdir=~/some/dir
# section1.enablesomefeature=true
# section1.enablesomeotherfeature=yes
# section2.anothersetting=42
myini --get section1.inputdir
# result:
# ~/some/dir
Dengan --type
opsi ini, Anda dapat "mengkanoniskan" pengaturan tertentu sebagai bilangan bulat, boolean, atau jalur (otomatis meluas ~
):
myini --get --type=path section1.inputdir # value '~/some/dir'
# result:
# /home/myuser/some/dir
myini --get --type=bool section1.enablesomeotherfeature # value 'yes'
# result:
# true
Contoh cepat dan kotor yang sedikit lebih kuat
Jadikan semua variabel mytool.ini
tersedia seperti SECTIONNAME_VARIABLENAME
di lingkungan saat ini, pertahankan ruang putih internal dalam nilai-nilai utama:
source <(
git config -f mytool.ini --list \
| sed 's/\([^.]*\)\.\(.*\)=\(.*\)/\U\1_\2\E="\3"/'
)
Apa yang dilakukan ekspresi sed, dalam bahasa Inggris, adalah
- menemukan sekelompok karakter non-periode hingga periode, mengingatnya sebagai
\1
, lalu
- menemukan sekelompok karakter hingga tanda sama dengan, mengingat itu sebagai
\2
, dan
- menemukan semua karakter setelah tanda sama dengan
\3
- akhirnya, di string pengganti
- nama bagian + nama variabel adalah huruf besar, dan
- bagian nilai dikutip ganda, jika mengandung karakter yang memiliki arti khusus untuk shell jika tidak dikutip (seperti spasi)
The \U
dan \E
urutan dalam string pengganti (yang atas-hal bagian dari string pengganti) adalah GNU sed
ekstensi. Pada macOS dan BSD, Anda hanya akan menggunakan banyak -e
ekspresi untuk mencapai efek yang sama.
Berurusan dengan kutipan dan spasi kosong dalam nama bagian (yang git config
memungkinkan) dibiarkan sebagai latihan untuk pembaca.:)
Menggunakan nama bagian sebagai kunci ke dalam array asosiatif Bash
Diberikan:
; foo.ini
[foobar]
session=foo
path=/some/path
[barfoo]
session=bar
path=/some/path
Ini akan menghasilkan hasil yang diminta OP, hanya dengan mengatur ulang beberapa tangkapan dalam ekspresi pengganti sed, dan akan bekerja dengan baik tanpa GNU sed:
source <(
git config -f foo.ini --list \
| sed 's/\([^.]*\)\.\(.*\)=\(.*\)/declare -A \2["\1"]="\3"/'
)
Saya memprediksi mungkin ada beberapa tantangan dengan mengutip untuk .ini
file dunia nyata , tetapi berfungsi untuk contoh yang diberikan. Hasil:
declare -p {session,path}
# result:
# declare -A session=([barfoo]="bar" [foobar]="foo" )
# declare -A path=([barfoo]="/some/path" [foobar]="/some/path" )