2017-05-12 105 views
-1

我是shell腳本編程的新手,我有一個需要使用示例的解釋。我有一個屬性文件,如下圖所示,將包含數據:從bash腳本中讀取ini文件的屬性

object1 : propertyA 

object2 : property1 property2 

object3 : propertyxyz 

注:整體來說,我有一些對象,可以有任意數量的屬性。我需要將其保存在屬性文件中,以便根據需要更改它。

所有我需要的是,如果我得到對象3作爲用戶輸入,然後我的代碼應該打印所有相應的屬性。

我已經嘗試使用.ini文件,但我不想使用任何外部解析器。在這種情況下,bash似乎沒有幫助我。如果我使用grep,那麼我將不得不使用一些正則表達式來分割屬性。

我創建.ini文件:

[object1] 

property=propertyA 


[object2] 

property=property1 

property=property2 

[object3] 

property=propertyxya 

我要尋找其中,如果我選擇一個對象(這在INI文件情況下,它是一款)溶液,然後我應該得到的所有屬性在一個數組中。

那麼有沒有什麼東西是在bash中預定義的,還是我只需要使用grep n regex來編寫。

+1

'awk'怎麼樣,最適合這個? – Inian

回答

2

它可以很容易使用Awk完成,只是做了下面的內容存儲在一個bash陣列。

read -p "Enter object to get properties for: " objectname 
all_properties=($(awk -F '=' -v input="${objectname}" '$1 ~ input{flag=1; next} $1 ~ /\[object/{flag=0; next} flag && NF {split($0,arr,"="); print arr[2] } config.ini)) 

現在環路陣列打印的屬性,

for property in "${all_properties[@]}"; do 
    printf "%s\n" "$property" 
done 

(或)只是

printf "%s\n" "${all_properties[@]}" 

Awk命令的工作如下: -

  1. 獲取用戶輸入一個變量並傳遞到Awk使用-v語法,做一個正則表達式匹配$1 ~ input來匹配含有用戶輸入的線,說object1
  2. 我使一個標誌,開始標記上,病房從該行線和復位一旦下一個對象開始的標誌,看$1 ~ /\[object/{flag=0; next}
  3. 條件flag && NF負責僅處理非空行和僅處理請求對象之後的屬性值。
  4. 現在在選定的行上,使用函數Awk,我們可以提取屬性的值並打印出來,這些值將在以後存儲在數組中。

將與read線和下面所顯示的bash腳本她邦設置爲#!/bin/bash線並運行它。

E.g.在一個完整的腳本中作爲

#!/usr/bin/bash 
read -p "Enter object to get properties for: " objectname 
all_properties=($(awk -F '=' -v input="${objectname}" '$1 ~ input{flag=1; next} $1 ~ /\[object/{flag=0; next} flag && NF {split($0,arr,"="); print arr[2] }' config.ini)) 

printf "%s\n" "${all_properties[@]}" 

在腳本上運行幾個示例。

$ bash script.sh 
Enter object to get properties for: object1 
propertyA 

$ bash script.sh 
Enter object to get properties for: object2 
property1 
property2 

$ bash script.sh 
Enter object to get properties for: object3 
propertyxya 
+0

你在哪裏通過部分ID在這裏。我可以看到你正在讀取參數,但你與「屬性」匹配,你能解釋一些更多..我將傳遞對象id作爲輸入,然後讀取所有屬性。 – Onki

+0

@Haj:你能看到更新的答案,並且知道它是否有效嗎? – Inian

+0

它似乎並沒有爲我工作。我的懷疑是,你正在使用「對象」作爲關鍵字,以達到下一部分。但對於我的案例,對象具有隨機名稱,沒有我們可以使用的常用字符。它只是我要在[] – Onki

0

隨着awk我們可以爲[對象]行正則表達式,我們只是捕捉到它。然後,我們已爲property=線,這裏正則表達式,我們加入了對象的屬性:

awk ' 
/^\[[a-z0-9]*\]$/ { obj=$0 } 
/^property=.*/ { print obj $0 } 
' filename.ini 

它產生中間輸出:

[object1]property=propertyA 
[object2]property=property1 
[object2]property=property2 
[object3]property=propertyxya 

然後,獲取屬性的,比方說,[對象2],我們只需使用grepsed

obj=object2 
result=$(echo $(awk ' 
/^\[[a-z0-9]*\]$/ { obj=$0 } 
/^property=.*/ { print obj $0 } 
' filename.ini | grep '^\['$obj'\]' | sed 's/.*property=//')) 

這將產生:

result=property1 property2 
0

我會做這樣的事情,在這裏XXXXXXX是對象名稱:

awk '/\[XXXXXXX\]/{flag=1;next}/\[.*\]/{flag=0}flag && NF' test.ini 

例如:

awk '/\[object1\]/{flag=1;next}/\[.*\]/{flag=0}flag && NF' test.ini 
property=propertyA 

awk '/\[object2\]/{flag=1;next}/\[.*\]/{flag=0}flag && NF' test.ini 
property=property1 
property=property2 

awk '/\[object3\]/{flag=1;next}/\[.*\]/{flag=0}flag && NF' test.ini 
property=propertyxya 

看到這個職位的詳細信息:How to select lines between two patterns?

對於陣列中的格式,這將取決於該數組應該是什麼樣子

+0

@Haj如果唯一的目的是顯示值而不保留鍵,那麼可以使用以下腳本:'awk -F「=」'/ \ ['「$ 1」 '\]/{flag = 1; next}/\ [。* \]/{flag = 0} flag && NF {print $ 2}'config.ini'並按以下方式調用它:'script.sh objectName' – Esteban

0

有它提供了一個函數來分析INI文件的項目:bash_ini_parser

它需要的bash而已,沒有其他工具需要。