Якщо у вас Git доступний і все в порядку з обмеженням неможливості використовувати підкреслення в ключових іменах, ви можете використовувати git config
як аналізатор / редактор INI загального призначення.
Він буде обробляти аналіз клавіш / значень пари навколо =
та відкидати незначну пробіл, плюс ви отримуєте коментарі (і ;
та #
) і вводите примус в основному безкоштовно. .ini
Нижче я включив повний робочий приклад для введення та бажаного виходу ОП (асоціативні масиви Баша).
Однак, з таким конфігураційним файлом
; mytool.ini
[section1]
inputdir = ~/some/dir
enablesomefeature = true
enablesomeotherfeature = yes
greeting = Bonjour, Monde!
[section2]
anothersetting = 42
… За умови, що вам просто потрібне швидке і брудне рішення, і ви не одружені з ідеєю встановлення налаштувань в асоціативному масиві Bash, ви можете піти якнайменше:
eval $(git config -f mytool.ini --list | tr . _)
# or if 'eval' skeeves you out excessively
source <(git config -f mytool.ini --list | tr . _)
що створює змінні середовища, названі sectionname_variablename
в поточному середовищі. Це, звичайно, працює лише в тому випадку, якщо ви можете довіритися, що жодне з ваших значень ніколи не буде містити періоду чи пробілу (див. Нижче для більш надійного рішення).
Інші прості приклади
Отримання довільних значень за допомогою функції оболонки для збереження набору тексту:
function myini() { git config -f mytool.ini; }
Псевдонім також буде нормальним, але і вони зазвичай не розширюються в сценарії оболонки [ 1 ], і все одно псевдоніми витісняються функціями оболонки "майже для будь-яких цілей" [ 2 ], повідомляється на сторінці чоловіка Баша .
myini --list
# result:
# section1.inputdir=~/some/dir
# section1.enablesomefeature=true
# section1.enablesomeotherfeature=yes
# section2.anothersetting=42
myini --get section1.inputdir
# result:
# ~/some/dir
За допомогою цього --type
параметра ви можете "канонізувати" певні налаштування як цілі числа, булеві або шляхи (автоматично розширюються ~
):
myini --get --type=path section1.inputdir # value '~/some/dir'
# result:
# /home/myuser/some/dir
myini --get --type=bool section1.enablesomeotherfeature # value 'yes'
# result:
# true
Трохи більш надійний приклад швидкого і брудного
Зробіть усі змінні mytool.ini
доступними, як SECTIONNAME_VARIABLENAME
у поточному середовищі, зберігаючи внутрішнє пробіл у ключових значеннях:
source <(
git config -f mytool.ini --list \
| sed 's/\([^.]*\)\.\(.*\)=\(.*\)/\U\1_\2\E="\3"/'
)
Те, що робить вираз sed, англійською мовою
- знаходячи купу неперіодичних символів до періоду, пам’ятаючи про те, що, як
\1
тоді
- знаходячи купу символів до знаку рівності, пам’ятаючи, що як
\2
і
- знаходження всіх символів після знака рівності як
\3
- нарешті, у рядку заміни
- назва розділу + ім'я змінної має верхній регістр, і
- частина значення подвійне цитування, якщо вона містить символи, які мають спеціальне значення для оболонки, якщо вони не цитуються (наприклад, пробіл)
Послідовності \U
та \E
послідовності в рядку заміни (який є верхній регістр цієї частини рядка заміни) є sed
розширенням GNU . Для macOS та BSD ви просто використовуватимете кілька -e
виразів, щоб досягти однакового ефекту.
Робота із вбудованими цитатами та пробілами в назвах розділів (що git config
дозволяє) залишається вправою для читача.:)
Використання імен розділів як клавіш в асоціативному масиві Bash
Подано:
; foo.ini
[foobar]
session=foo
path=/some/path
[barfoo]
session=bar
path=/some/path
Це дасть результат, про який вимагає ОП, просто переставивши деякі захоплення в виразі заміни sed, і буде добре працювати без GNU sed:
source <(
git config -f foo.ini --list \
| sed 's/\([^.]*\)\.\(.*\)=\(.*\)/declare -A \2["\1"]="\3"/'
)
Я прогнозую, що з цитуванням реального .ini
файлу можуть виникнути певні труднощі , але це працює на наведеному прикладі. Результат:
declare -p {session,path}
# result:
# declare -A session=([barfoo]="bar" [foobar]="foo" )
# declare -A path=([barfoo]="/some/path" [foobar]="/some/path" )