Saya mencoba mengubah file ini menjadi variabel array bash. Sampel ini adalah sebagai berikut:
[foobar]
session=foo
path=/some/path
[barfoo]
session=bar
path=/some/path
jadi ini menjadi:
session[foobar]=foo
path[foobar]=/some/path
session[barfoo]=bar
dan seterusnya.
Saat ini, saya hanya bisa membuat perintah ini
awk -F'=' '{ if ($1 ~ /^\[/) section=$1; else if ($1 !~ /^$/) print $1 section "=" $2 }'
Juga, masalah lain adalah, tidak mengambil ruang dekat =
menjadi pertimbangan. Saya pikir sed
mungkin lebih cocok untuk pekerjaan ini, tetapi saya tidak tahu bagaimana memegang dan menyimpan variabel sementara untuk nama bagian dalam sed
.
Jadi, ada ide bagaimana melakukan ini?
ini
parser ini dibash
.Jawaban:
Gawk menerima ekspresi reguler sebagai pembatas bidang. Berikut ini menghilangkan spasi di sekitar tanda sama dengan, tetapi mempertahankannya di sisa garis. Kutipan ditambahkan di sekitar nilai sehingga ruang-ruang itu, jika ada, dipertahankan ketika tugas Bash dilakukan. Saya berasumsi bahwa nama bagian akan menjadi variabel numerik, tetapi jika Anda menggunakan Bash 4, akan mudah untuk mengadaptasi ini menggunakan array asosiatif dengan nama bagian itu sendiri sebagai indeks.
Perhatikan bahwa Anda mungkin ingin juga melakukan penghapusan spasi yang ditampilkan Khaled (hanya $ 1 dan bagian) karena nama variabel Bash tidak boleh mengandung spasi.
Juga, metode ini tidak akan berfungsi jika nilainya mengandung tanda yang sama.
Teknik lain adalah dengan menggunakan Bash
while read
loop dan melakukan tugas saat file dibaca, menggunakandeclare
yang aman dari sebagian besar konten berbahaya.Sekali lagi, array asosiatif dapat dengan mudah didukung.
sumber
Saya akan menggunakan skrip python sederhana untuk pekerjaan ini karena telah dibangun di INI parser :
dan kemudian di bash:
Tentu, ada implementasi yang lebih pendek di awk, tapi saya pikir ini lebih mudah dibaca dan lebih mudah untuk dipelihara.
sumber
print "declare -A %s" % (sec)
eval
:source <(cat in.ini | ./ini2arr.py)
Jika Anda ingin menghilangkan ruang ekstra, Anda dapat menggunakan fungsi bawaan
gsub
. Misalnya, Anda dapat menambahkan:Ini akan menghapus semua ruang. Jika Anda ingin menghapus spasi di awal atau akhir token, Anda dapat menggunakannya
sumber
Inilah solusi bash murni.
Ini adalah versi baru dan lebih baik dari apa yang diposting chilladx:
https://github.com/albfan/bash-ini-parser
Untuk contoh awal yang sangat mudah diikuti: Setelah Anda mengunduh ini, cukup salin file
bash-ini-parser
, danscripts/file.ini
ke direktori yang sama, lalu buat skrip pengujian klien menggunakan contoh yang saya berikan di bawah ini ke direktori yang sama juga.Berikut ini beberapa peningkatan lebih lanjut yang saya buat pada skrip bash-ini-parser ...
Jika Anda ingin dapat membaca file ini dengan akhiran Windows serta Unix, tambahkan baris ini ke fungsi cfg_parser segera setelah yang membaca file:
Jika Anda ingin membaca file yang memiliki izin akses terbatas, tambahkan fungsi opsional ini:
sumber
chmod 777
. Meskipun praktik teduh paling baik, pasti tidak perlu membuat file ini dapat dieksekusi. Pendekatan yang lebih baik akan digunakansudo
untuk membaca file, bukan untuk mengacaukan izin.Selalu dengan asumsi memiliki Python ConfigParser sekitar, orang dapat membangun fungsi pembantu shell seperti ini:
$IFACE
dan$param
masing-masing bagian parameter.Pembantu ini kemudian memungkinkan panggilan seperti:
Semoga ini membantu!
sumber
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
... asalkan Anda hanya membutuhkan solusi cepat dan kotor, dan tidak menikah dengan gagasan memiliki pengaturan dalam array asosiatif Bash, Anda bisa lolos dengan sesedikit:
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:
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 .
Dengan
--type
opsi ini, Anda dapat "mengkanoniskan" pengaturan tertentu sebagai bilangan bulat, boolean, atau jalur (otomatis meluas~
):Contoh cepat dan kotor yang sedikit lebih kuat
Jadikan semua variabel
mytool.ini
tersedia sepertiSECTIONNAME_VARIABLENAME
di lingkungan saat ini, pertahankan ruang putih internal dalam nilai-nilai utama:Apa yang dilakukan ekspresi sed, dalam bahasa Inggris, adalah
\1
, lalu\2
, dan\3
The
\U
dan\E
urutan dalam string pengganti (yang atas-hal bagian dari string pengganti) adalah GNUsed
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:
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:
Saya memprediksi mungkin ada beberapa tantangan dengan mengutip untuk
.ini
file dunia nyata , tetapi berfungsi untuk contoh yang diberikan. Hasil:sumber