หากคุณมี Git และตกลงกับข้อ จำกัด ที่ไม่สามารถใช้เครื่องหมายขีดล่างในชื่อคีย์คุณสามารถใช้git config
เป็นตัวแยกวิเคราะห์ / ตัวแก้ไข INI เอนกประสงค์
มันจะจัดการแยกคีย์คู่ / ค่าจากรอบ ๆ=
และยกเลิกช่องว่างที่ไม่มีนัยสำคัญรวมทั้งคุณได้รับความคิดเห็น (ทั้ง;
และ#
) และประเภทการข่มขู่โดยทั่วไปฟรี ฉันได้รวมตัวอย่างการทำงานที่สมบูรณ์สำหรับอินพุตของ OP .ini
และเอาท์พุทที่ต้องการ (อาเรย์เชื่อมโยง Bash) ไว้ด้านล่าง
อย่างไรก็ตามให้ไฟล์ config แบบนี้
; mytool.ini
[section1]
inputdir = ~/some/dir
enablesomefeature = true
enablesomeotherfeature = yes
greeting = Bonjour, Monde!
[section2]
anothersetting = 42
... หากคุณต้องการวิธีแก้ปัญหาที่รวดเร็วและสกปรกและไม่ได้แต่งงานกับความคิดของการตั้งค่าในอาเรย์ของ Bash associative คุณสามารถทำได้โดยใช้:
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
ตัวเลือกนี้คุณสามารถตั้งค่า "canonicalize" เป็นจำนวนเต็มบูลีนหรือพา ธ (ขยายโดยอัตโนมัติ~
):
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"/'
)
สิ่งที่แสดงออกอย่างใจเย็นกำลังทำในภาษาอังกฤษคือ
- การค้นหากลุ่มของอักขระที่ไม่ใช่ช่วงเวลาจนถึงจุดหนึ่งโดยจดจำว่าเป็น
\1
แล้ว
- การค้นหากลุ่มของอักขระจนถึงเครื่องหมายเท่ากับให้จำว่าเป็น
\2
และ
- การค้นหาตัวอักษรทั้งหมดหลังจากเครื่องหมายเท่ากับ
\3
- ในที่สุดในสตริงแทนที่
- ชื่อส่วน + ชื่อตัวแปรเป็นตัวพิมพ์ใหญ่และ
- ส่วนของค่าคือการเสนอราคาสองครั้งในกรณีที่มันมีตัวละครที่มีความหมายพิเศษกับเปลือกถ้าไม่ได้ยกมา (เช่นช่องว่าง)
\U
และ\E
วนเวียนอยู่ในสตริงทดแทน (ซึ่งบนกรณีที่เป็นส่วนหนึ่งของสตริงทดแทน) เป็น GNU sed
นามสกุล สำหรับ macOS และ BSD คุณเพียงแค่ใช้หลาย-e
นิพจน์เพื่อให้ได้ผลลัพธ์ที่เหมือนกัน
การจัดการกับอัญประกาศและช่องว่างที่ฝังอยู่ในชื่อส่วน (ซึ่งgit config
อนุญาตให้) ถูกทิ้งไว้เป็นแบบฝึกหัดสำหรับผู้อ่าน:)
การใช้ชื่อส่วนเป็นคีย์ในอาเรย์ของ Bash
ได้รับ:
; foo.ini
[foobar]
session=foo
path=/some/path
[barfoo]
session=bar
path=/some/path
สิ่งนี้จะสร้างผลลัพธ์ที่ OP ต้องการโดยเพียงแค่จัดเรียงบางส่วนใหม่ในนิพจน์แทนที่ 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" )